当将组件存储在状态中时,在更改其道具时它不再重新渲染吗?

时间:2019-09-30 11:32:31

标签: javascript reactjs

在一个特定的业务案例中,我有一系列线性排列的组件,但是顺序可能会改变。例如,我们有一个父组件:

export const Component = () => {

    const [data, setData] = useState(null);

    const [nextComponent, setNextComponent] = useState(null);

    return (
        //... component code here
        {nextComponent}
    );
}

Component代码中将包含可以更改下一个组件的按钮:

onClick={() => setNextComponent(<SomeComponent data={data} setData={setData} />)}

如果通过在data中调用setData来更改SomeComponent,则该组件不会使用新的data道具值重新呈现。

我知道这与SomeComponent处于状态存储有关,但无法理解为什么data不会在SomeComponent中更新-当然data只是指向内存位置的指针,因此在父级和子级之间应该具有相同的值吗?

1 个答案:

答案 0 :(得分:1)

这是因为仅当函数data作为SomeComponent回调的一部分被调用时,setNextComponent道具才针对onClick进行更新。

做到这一点的“正确方法”是将对SomeComponent至关重要的数据保持在其父状态下,然后将其作为该孩子的有条件渲染的一部分传递给下一个。

const ChildComponent = ({ data, setData }) => (
  <React.Fragment>
    <span>Current Data: {JSON.stringify(data)}</span>
    <input onChange={({target}) => setData(target.value)} placeholder="Enter New Data" />
  </React.Fragment>
);

const ParentComponent = () => {
  const CHILD_TYPES = { signIn: SomeComponent, signOut: OtherComponent };

  // keep track which component you want to be showing based on parent state
  const [activeComponentType, setActiveComponentType] = useState('signIn');

  // keep track of the data required for the child component(s)
  const [data, setData] = useState(null);

  // find and use the correct class for the current child type
  // (you could do this without an extra variable by using `React.createClass`)
  const ActiveComponentClass = CHILD_TYPES[activeComponentType];
  return (<ActiveComponentClass data={data} setData={setData} />);
}

此外,您应该考虑不将组件存储在状态中。这是不好的做法,通常无法按您期望的方式工作。