onChange 事件仅在状态由 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 状态获取。

您目前是:

  1. 获取 Redux 状态(通过 props),并将其复制到componentDidMount中的组件状态。
  2. 从 props 填充输入的value(从 Redux 状态)。
  3. 通过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]
]
})
...
}

这样,当您的状态更新时,表单的"当前"值将在重新呈现时更新,并且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)
);

最新更新