javascript - 当数组 prop 更改时,React 子组件不会重新渲染

标签 javascript reactjs react-hooks

我的主应用程序有两个子组件,两个子组件都接收相同的 model 属性。

第一个子组件处理来自 model.myNumberProperty 的数字属性,第二个子组件处理来自 model.myArrayProperty 的数组属性

更改子组件一中的 model.myNumberProperty 会触发重新渲染,但 更改子组件二中的 model.myArrayProperty 不会

function App() {
  const model = MyModel();

  return (
    <div className="App">
      Main app
      <ComponentOne dataObject={model} />
      <ComponentTwo dataObject={model} />
    </div>
  );
}

export default function MyModel() {
  let _propOne = 0;
  let _propTwo = ["one"];

  const propOne = () => {
    return _propOne;
  };
  const propTwo = () => {
    return _propTwo;
  };

  const modifyPropOne = () => {
    _propOne++;
    console.log("modifying prop one", _propOne);
  };

  const modifyPropTwo = () => {
    _propTwo.push("new element");
  };

  return Object.freeze({ propOne, propTwo, modifyPropOne, modifyPropTwo });
}


const ComponentOne = props => {
  const [propOne, setPropOne] = useState(props.dataObject.propOne());

  const onButtonOneClick = () => {
    props.dataObject.modifyPropOne();
    setPropOne(props.dataObject.propOne());
  };

  return (
    <div>
      <p>Hello ComponentOne:</p>

      <button onClick={onButtonOneClick}>ModifyPropOne</button>
      <p>{propOne}</p>
    </div>
  );
};

const ComponentTwo = props => {
  const [propTwo, setPropTwo] = useState(props.dataObject.propTwo());

  const onButtonTwoClick = () => {
    props.dataObject.modifyPropTwo();
    setPropTwo([...props.dataObject.propTwo()]);
    console.log('Prop two', props.dataObject.propTwo());
  };
  return (
    <div>
      <p>Hello ComponentTwo</p>

      <button onClick={onButtonTwoClick}>ModifyPropTwo</button>
      {propTwo.map((value, index) => (
        <p key={index}>{value}</p>
      ))}
    </div>
  );
};

请查看this CodeSandbox测试案例。

我正在使用 React Hooks。 我的问题的解决方案应该只是 React,所以没有 Redux 或其他第 3 方库。

请注意,我的模型是一个卡住对象以强制封装,因此我不能只重新创建整个对象。示例中的模型是一个简化的模型,在我的实际项目中,它是一个处理大量数组的复杂纸牌游戏对象。

最佳答案

调用 setState 时,React 会生成 shallow comparison与之前的状态并决定渲染阶段是否应该继续。

在您的情况下,它具有相同的引用,因此不会触发渲染。

要修复此问题,请将数组的副本设置为新状态。

const onButtonTwoClick = () => {
  props.dataObject.modifyPropTwo();
  //                v Make a new copy.
  setPropTwo([...props.dataObject.propTwo()]);
};

引用The power of not mutating Data .

Edit updateArrayProp

关于javascript - 当数组 prop 更改时,React 子组件不会重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58576702/

相关文章:

javascript - 如果在事件处理程序之前或之间有等待调用,React 不会在事件处理程序中批处理 setState 调用

javascript - 当其父节点具有禁用类时排除元素上的悬停

javascript - ReactJS - 父级更改后子级无法正确重新渲染

javascript - undefined 不是一个函数(评估'_this.props.navigation.navigate')

javascript - 有哪些常见的 Redux Toolkit 的 CreateAsyncThunk 用例

javascript - 如何使用 react 钩子(Hook) react.js 一次更新多个状态

async-await - 类型错误 : Cannot read property 'type' of undefined (redux toolkit)

php - 如何在将变量加载到 cake php 的页面之前将变量附加到所有 javascript 文件?

javascript - 如何加载与 html 混合的 JavaScript

javascript - #id 以数字结尾的通用 CSS