我最近发现自己写了很多代码,看起来像这样:
const SomeComponent: React.FunctionComponent<SomeComponentProps> = props => {
  const { value } = props;
  const [thisValue, setThisValue] = React.useState(value);
  const handleChange = React.useCallback(e => {
    setThisValue(e.target.value);
  }, []);
 ....在这里,我从props传入一个初始化值,然后在组件中修改该值。
它做了我想做的,但我开始怀疑它了。
这是反模式吗?
发布于 2019-11-01 11:54:33
这是一篇不错的(有点旧的)文章,讨论了使用props初始化状态:
https://medium.com/@justintulk/react-anti-patterns-props-in-initial-state-28687846cc2e
React文档称其为反模式:
在getInitialState中使用属性来生成状态通常会导致“事实来源”的重复,即实际数据所在的位置。这是因为getInitialState只在组件首次创建时调用。
文档中有一个例外,那就是:
仅当有意忽略属性更新时才使用此模式。在这种情况下,将属性重命名为initialColor或defaultColor是有意义的。然后,您可以在必要时通过更改组件的键来强制组件“重置”其内部状态。
话虽如此,我也发现自己时不时地这样做。
我发现它有用的一个例子是允许用户编辑复杂状态的组件。您可以使用props初始化状态,组件将在内部处理对此状态的更改。如果要在道具更改时重置状态,则有两种选择:
第一种方法是侦听更改并调用setState,如下所示:
componentDidUpdate(prevProps, prevState) {
  if (prevProps.inputValue !== this.props.inputValue) {
    this.setState({ inputVal: this.props.inputValue })
  }
}推荐的选项是给组件一个键,这个键取决于应该触发重置的道具。然后当属性改变时,组件状态将被重新初始化:
<MyComponent initProp={someValue} key={`key_${someValue}`/>我只建议将这些选项用于复杂的状态。在大多数示例中,父组件可以保持此状态,内部组件可以使用回调来更新父组件的更改。
发布于 2019-11-01 18:52:52
这是一个反模式的例子,在这个例子中,你不让道具领先,只在挂载或构造函数上设置状态。我正在尝试创建一个有状态的表单组件,但在用户提交它时会向消费者(父组件)发出信号。消费者可以选择重置表单:
function App() {
  const [initial, setInitial] = React.useState({
    name: 'init',
  });
  const submit = React.useCallback(form => {
    console.log('form is:',form);
  }, []);
  return (
    <div>
      <button onClick={() => setInitial({ name: 'reset' })}>
        reset
      </button>
      <Form initial={initial} submit={submit} />
    </div>
  );
}
function Form({ initial, submit }) {
  const [form, setForm] = React.useState(initial);
  const onChange = React.useCallback(e => {
    const name = e.target.value;
    setForm(form => ({ ...form, name }));
  }, []);
  const onSubmit = React.useCallback(
    e => {
      e.preventDefault();
      setForm(form => {
        submit(form);
        return form;
      });
    },
    [submit]
  );
  //witout this effect reset will not work
  React.useEffect(() => setForm(initial), [initial]);
  return (
    <form onSubmit={onSubmit}>
      <input
        type="text"
        value={form.name}
        onChange={onChange}
      />
      <button type="submit">Save</button>
    </form>
  );
}
ReactDOM.render(<App />, document.getElementById('root'));<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
https://stackoverflow.com/questions/58653738
复制相似问题