反应/功能组件/道具更改/ getDerivedStateFromProps

时间:2019-03-22 12:08:14

标签: javascript reactjs components state

让我们说我正在做一个简单的CRUD应用。我的功能组件基本上就是表单。

  • 在创建的情况下,我通过道具传入一个空对象
  • 在UPDATE情况下,我通过prop传递了一个带有值的对象(我通过API调用将数据放在父组件中)

我看起来像这样:

const MyForm = (props) => {

 const [myValues, setMyValues] = useState(props.myValues);
 const [errors, setErrors] = useState(0);
 (...)
}

在UPDATE情况下,我(当然)遇到了这样的问题:安装组件时props.myValues仍然为空,而当从父组件进行的api调用完成时没有再次设置(更新),因此表单值为空。

使用类组件,我可以通过 getDerivedStateFromProps()解决该问题。功能组件中是否有类似内容?还是我从一开始就做错了?感谢您的任何建议!

3 个答案:

答案 0 :(得分:1)

是的,您当然可以使用useEffect

在您的情况下,代码应如下所示:

const MyForm = (props) => {

 const [myValues, setMyValues] = useState(props.myValues);
 const [errors, setErrors] = useState(0);

 useEffect(() => {
   setMyValues(props.myValues);
 }, [props.myValues]);

}

答案 1 :(得分:0)

写时:

const [myValues, setMyValues] = useState(props.myValues);

然后myValues道具仅用于初始化myValues状态。 Dan Abramov在his latest article中谈到了这一点。
 我建议:
1.将myValues属性重命名为initialValues
2.提交后调用api,然后根据结果更改状态。

它看起来像:

const MyForm = (props) => {
  const { initialValues, onSubmit } = this.props
  const [myValues, setMyValues] = useState(initialValues);
  ...
  const handleSubmit = () => {
     // Assume that onSubmit is a call to Fetch API
     onSubmit(myValues).then(response => response.json())
                       .then(updatedValues => setMyValues(updatedValues)) 
  }
} 

答案 2 :(得分:0)

另一种实现方法是Fully uncontrolled component with a key策略。如果您走那条路线,您的组件将保持不变:

const MyForm = (props) => {

 const [myValues, setMyValues] = useState(props.myValues);
 const [errors, setErrors] = useState(0);
 (...)
}

但是它的用法还有一个额外的内容:

<MyForm myValues={myValues} key={myValues} />

像这样使用key属性意味着,如果myValues更改,则将创建此组件的新实例,这意味着您为内部myValues状态提供的默认值将重置为新值值是。

这避免了useEffect时出现的双重渲染,但是要付出新的组件实例的代价。如果您在单个输入级别上执行此操作,我认为这不是问题,但是您可能不想重建整个表单。