Javascript 将状态与道具同步,以实现reactjs中表单输入的双向绑定

Javascript 将状态与道具同步,以实现reactjs中表单输入的双向绑定,javascript,model,redux,normalize,Javascript,Model,Redux,Normalize,我有一个很长的表单(准确地说是75个输入),因为我使用redux来管理我的应用程序状态,每当我想编辑这个表单时,我都想将表单状态设置为允许编辑的道具 示例代码: 类VisitCard扩展组件{ 建造师(道具){ super(props);//props.visit={name:'randome name',data:'etc..} this.state=Object.assign({},props.visit); this.bindInput=this.bindInput.bind(this);

我有一个很长的表单(准确地说是75个输入),因为我使用redux来管理我的应用程序状态,每当我想编辑这个表单时,我都想将表单状态设置为允许编辑的道具

示例代码:
类VisitCard扩展组件{
建造师(道具){
super(props);//props.visit={name:'randome name',data:'etc..}
this.state=Object.assign({},props.visit);
this.bindInput=this.bindInput.bind(this);
}
//BindInput将为输入返回道具,以实现双向绑定
bindInput(配置){
const{name,…props}=config;
返回{
值:this.state[名称],
onChange:event=>this.setState({[name]:event.target.value}),
…道具
}
}
render(){
返回
}
}
上面的代码工作得很完美,问题是当这个组件挂载时,它会给我错误“无法在现有状态转换期间更新”

有时,如果props中未预定义值,则输入值将未定义,因此从服务器加载props并更新组件后,我会出现另一个错误“尝试将输入从非受控更改为受控”,这是因为
此状态[name]
未定义,然后我得到一个值


那我做错了什么?如何将组件的状态与props值链接,并确保如果props发生更改,状态也会发生更改,而同时,如果状态发生更改,则不会影响props。

我希望修改代码以匹配以下逻辑将解决您的问题。在代码中查找注释以获得解释

class VisitCard extends Component {
  constructor(props) {
    super(props); 
    //set your state to have a key that holds your prop value.
    this.state = { visit: props.visit };
    this.bindInput = this.bindInput.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    //if your props is received after the component is mounted, then this function will update the state accordingly.
    if(this.props.visit !== nextProps.visit) {
     this.setState({visit: nextProps.visit});
    }
  }

  bindInput(config){
    const {name,...props} = config;
    // return defaultValue which you get from the props.
    // you can add `value: this.state.visit[name]` to the below object only if you want your input to be controlled, else it can be ignored.
    return {
      defaultValue   : this.props.visit[name],
      onChange: event => this.setState(
            {visit: { ...this.state.visit,
                      [name]:event.target.value}
            }),
      ...props
    }
  }

  render(){
   // render empty if your props has not yet arrived.
  if(!this.props.visit) {
    return (<div />);
  }

  // render after you have values in props
  return (<div>
   <input {...this.bindInput({name:'name', type:'text'})} />
   <input {...this.bindInput({name:'data', type:'text'})} />
  </div>);

  }
}
类VisitCard扩展组件{
建造师(道具){
超级(道具);
//将您的状态设置为具有保存道具值的关键点。
this.state={visit:props.visit};
this.bindInput=this.bindInput.bind(this);
}
组件将接收道具(下一步){
//如果在安装组件后收到道具,则此功能将相应地更新状态。
if(this.props.visit!==nextrops.visit){
this.setState({visit:nextrops.visit});
}
}
bindInput(配置){
const{name,…props}=config;
//返回从道具获取的默认值。
//只有当您希望控制输入时,才可以将'value:this.state.visit[name]`添加到下面的对象,否则可以忽略它。
返回{
defaultValue:this.props.visit[name],
onChange:event=>this.setState(
{访问:{……这是国事访问,
[名称]:event.target.value}
}),
…道具
}
}
render(){
//如果您的道具尚未到达,则渲染为空。
如果(!this.props.visit){
返回();
}
//在道具中具有值后渲染
返回(
);
}
}
class VisitCard extends Component {
  constructor(props) {
    super(props); 
    //set your state to have a key that holds your prop value.
    this.state = { visit: props.visit };
    this.bindInput = this.bindInput.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    //if your props is received after the component is mounted, then this function will update the state accordingly.
    if(this.props.visit !== nextProps.visit) {
     this.setState({visit: nextProps.visit});
    }
  }

  bindInput(config){
    const {name,...props} = config;
    // return defaultValue which you get from the props.
    // you can add `value: this.state.visit[name]` to the below object only if you want your input to be controlled, else it can be ignored.
    return {
      defaultValue   : this.props.visit[name],
      onChange: event => this.setState(
            {visit: { ...this.state.visit,
                      [name]:event.target.value}
            }),
      ...props
    }
  }

  render(){
   // render empty if your props has not yet arrived.
  if(!this.props.visit) {
    return (<div />);
  }

  // render after you have values in props
  return (<div>
   <input {...this.bindInput({name:'name', type:'text'})} />
   <input {...this.bindInput({name:'data', type:'text'})} />
  </div>);

  }
}