onChange 事件仅在 state 由 redux 管理时发生一次
onChange event is only occurring once when state is managed by redux
我正在从 redux 存储中获取一个包含单个对象的数组。
this.props.license :[0: {id: 24, domain: "xyz.com", app_url: "https...", purchase_code: "395"}]
然后创建一个表单来更新反应表单中的值。
但是当尝试更改值时,onChange
事件只发生一次。
我正在 React 组件中管理一个新状态,以保存我在 onChange
事件上所做的更改。
这是我编码的正确方式吗?
import React ,{Component} from 'react';
import {connect} from 'react-redux';
import * as actionCreators from '../../store/actions/index';
import Spinner from '../../components/Spinner/Spinner';
const DATABASE_LABELS={
id:'ID',
domain:'Domain',
app_url:'APP URL',
purchase_code:'Purchase Code',
}
class editLicense extends Component {
constructor(props){
super(props);
this.state={
editLicense:{}
}
}
onChangeHandler=(event, type)=>{
// [event.target.name]=[event.target.value]
let newLicense={...this.state.editLicense}
newLicense[type]=event.target.value
console.log(newLicense)
console.log('before',this.state.editLicense)
this.setState({
editLicense :{
...this.state.editLicense,
[event.target.name]:event.target.value
}
})
console.log(this.state.editLicense)
}
componentDidMount=()=>{
this.props.viewLicenceDetails(this.props.token, this.props.match.params.id)
this.setState({
editLicense:this.props.licenses[0]
})
console.log(this.state.editLicense)
}
render(){
let formdata=<Spinner/>;
if(!this.props.loading){
let license=Object.keys(this.props.licenses[0])
.map(key=>{
return [
key,
this.props.licenses[0][key]
]
})
let form=license.map((p, index)=>{
return(
<div className="form-group" key={p[0]}>
<label htmlFor={p[0]}> {DATABASE_LABELS[p[0]]} </label>
<input type="text" className="form-control"
id={p[0]}
value={p[1]}
name={p[0]}
onChange={(event) => this.onChangeHandler(event, p[0])} />
</div>)
})
formdata=(
<form>
{form}
<button type="submit" className="btn btn-primary">Submit</button>
</form>
)
}
return(
<div className="container">
{formdata}
</div>
)}
}
const mapStateToProps = (state)=>{
return({
token:state.auth.idToken,
licenses:state.license.licenses,
loading:state.license.loading,
err:state.license.error
})
}
const mapDispatchToProps = dispatch=>{
return({
updateLicenseData:(token, type, newVal)=>dispatch(actionCreators.updateLicense(token, type, newVal)),
viewLicenceDetails:(token, id)=>dispatch(actionCreators.fetchOneLicense(token, id))
})
}
export default connect(mapStateToProps, mapDispatchToProps)(editLicense);
问题标题有点误导。目前,您的状态并未完全由 Redux 管理,而只是最初从 Redux 状态中获取。
您目前是:
- 获取 Redux 状态(通过 props),并将其复制到
componentDidMount
中的组件状态。
- 从道具(从 Redux 状态)填充您的输入
value
。
- 正在通过
onChange
-> onChangeHandler
. 更新您的本地组件状态
(2) 是您当前的问题。你的 props 当前没有被改变(因为你没有调用任何 Redux 动作),所以你的 input
元素的值永远不会改变。这有点不直观,但这会导致更改仅被检测到一次。
您需要使用您的状态填充您的输入 value
道具。在您的 render()
函数中,尝试将 this.props.licenses[0]
的实例替换为 this.state.editLicense
:
if(!this.props.loading){
let license=Object.keys(this.state.editLicense)
.map(key=>{
return [
key,
this.state.editLicense[key]
]
})
...
}
这样,当您的状态更新时,表单的 'current' 值将在 re-render 上更新,并且 input
组件将得到完全控制。
旁注:
this.setState({
editLicense:this.props.licenses[0]
})
console.log(this.state.editLicense)
这不能保证有效。 setState
通常应被视为异步。如果你想在渲染周期之外响应更新的状态,你应该提供一个回调 setState
:
this.setState({
editLicense:this.props.licenses[0]
},
() => console.log(this.state.editLicense)
);
我正在从 redux 存储中获取一个包含单个对象的数组。
this.props.license :[0: {id: 24, domain: "xyz.com", app_url: "https...", purchase_code: "395"}]
然后创建一个表单来更新反应表单中的值。
但是当尝试更改值时,onChange
事件只发生一次。
我正在 React 组件中管理一个新状态,以保存我在 onChange
事件上所做的更改。
这是我编码的正确方式吗?
import React ,{Component} from 'react';
import {connect} from 'react-redux';
import * as actionCreators from '../../store/actions/index';
import Spinner from '../../components/Spinner/Spinner';
const DATABASE_LABELS={
id:'ID',
domain:'Domain',
app_url:'APP URL',
purchase_code:'Purchase Code',
}
class editLicense extends Component {
constructor(props){
super(props);
this.state={
editLicense:{}
}
}
onChangeHandler=(event, type)=>{
// [event.target.name]=[event.target.value]
let newLicense={...this.state.editLicense}
newLicense[type]=event.target.value
console.log(newLicense)
console.log('before',this.state.editLicense)
this.setState({
editLicense :{
...this.state.editLicense,
[event.target.name]:event.target.value
}
})
console.log(this.state.editLicense)
}
componentDidMount=()=>{
this.props.viewLicenceDetails(this.props.token, this.props.match.params.id)
this.setState({
editLicense:this.props.licenses[0]
})
console.log(this.state.editLicense)
}
render(){
let formdata=<Spinner/>;
if(!this.props.loading){
let license=Object.keys(this.props.licenses[0])
.map(key=>{
return [
key,
this.props.licenses[0][key]
]
})
let form=license.map((p, index)=>{
return(
<div className="form-group" key={p[0]}>
<label htmlFor={p[0]}> {DATABASE_LABELS[p[0]]} </label>
<input type="text" className="form-control"
id={p[0]}
value={p[1]}
name={p[0]}
onChange={(event) => this.onChangeHandler(event, p[0])} />
</div>)
})
formdata=(
<form>
{form}
<button type="submit" className="btn btn-primary">Submit</button>
</form>
)
}
return(
<div className="container">
{formdata}
</div>
)}
}
const mapStateToProps = (state)=>{
return({
token:state.auth.idToken,
licenses:state.license.licenses,
loading:state.license.loading,
err:state.license.error
})
}
const mapDispatchToProps = dispatch=>{
return({
updateLicenseData:(token, type, newVal)=>dispatch(actionCreators.updateLicense(token, type, newVal)),
viewLicenceDetails:(token, id)=>dispatch(actionCreators.fetchOneLicense(token, id))
})
}
export default connect(mapStateToProps, mapDispatchToProps)(editLicense);
问题标题有点误导。目前,您的状态并未完全由 Redux 管理,而只是最初从 Redux 状态中获取。
您目前是:
- 获取 Redux 状态(通过 props),并将其复制到
componentDidMount
中的组件状态。 - 从道具(从 Redux 状态)填充您的输入
value
。 - 正在通过
onChange
->onChangeHandler
. 更新您的本地组件状态
(2) 是您当前的问题。你的 props 当前没有被改变(因为你没有调用任何 Redux 动作),所以你的 input
元素的值永远不会改变。这有点不直观,但这会导致更改仅被检测到一次。
您需要使用您的状态填充您的输入 value
道具。在您的 render()
函数中,尝试将 this.props.licenses[0]
的实例替换为 this.state.editLicense
:
if(!this.props.loading){
let license=Object.keys(this.state.editLicense)
.map(key=>{
return [
key,
this.state.editLicense[key]
]
})
...
}
这样,当您的状态更新时,表单的 'current' 值将在 re-render 上更新,并且 input
组件将得到完全控制。
旁注:
this.setState({
editLicense:this.props.licenses[0]
})
console.log(this.state.editLicense)
这不能保证有效。 setState
通常应被视为异步。如果你想在渲染周期之外响应更新的状态,你应该提供一个回调 setState
:
this.setState({
editLicense:this.props.licenses[0]
},
() => console.log(this.state.editLicense)
);