react / 功能组件 / props改变 / getDerivedStateFromProps

IT技术 javascript reactjs components state
2021-05-13 02:42:08

假设我正在做一个简单的 CRUD 应用程序来响应。我的功能组件基本上只是表单。

  • 在 CREATE 的情况下,我通过 props 传入一个空对象
  • 在 UPDATE 案例中,我通过 props 传入一个带有值的对象(我通过 API 调用在父组件中获取了数据)

我看起来像这样:

const MyForm = (props) => {

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

在 UPDATE 的情况下,我(当然)遇到了这样的问题,即组件安装时 props.myValues 仍然为空,并且在父组件的 api 调用完成时不会再次设置(更新),从而使表单值为空.

使用类组件,我会用getDerivedStateFromProps()解决这个问题在功能组件中有类似的东西吗?还是我从一开始就做错了?感谢您的任何建议!

3个回答

是的,您当然可以使用useEffect.

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

const MyForm = (props) => {

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

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

}

另一种方法是具有关键策略完全不受控制的组件如果你走那条路,你的组件保持不变:

const MyForm = (props) => {

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

但是它的用法还有一个额外的部分:

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

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

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

当你写:

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

那么 myValues props 仅用于初始化 myValues 状态。Dan Abramov 在他的最新文章中谈到了这一点
我建议:
1. 将 myValues prop 重命名为 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)) 
  }
}