React:为什么当 prop 更改时子组件不更新

IT技术 javascript html reactjs
2021-02-26 22:50:43

为什么在下面的伪代码示例中,当 Container 更改 foo.bar 时,Child 不会重新渲染?

Container {
  handleEvent() {
    this.props.foo.bar = 123
  },

  render() {
    return <Child bar={this.props.foo.bar} />
}

Child {
  render() {
    return <div>{this.props.bar}</div>
  }
}

即使我forceUpdate()在修改Container中的值后调用,Child仍然显示旧值。

6个回答

更新孩子的属性“key”等于名称。每次密钥更改时,组件都会重新渲染。

Child {
  render() {
    return <div key={this.props.bar}>{this.props.bar}</div>
  }
}
谢谢你。我正在使用 redux 存储,并且在添加密钥之前无法重新渲染我的组件。(我使用了 uuid 库来生成随机密钥,并且成功了)。
2021-04-17 22:50:43
我使用索引作为键,但它无法正常运行。现在我正在使用 uuid,它很完美 :) 感谢 @Maiya
2021-04-19 22:50:43
在我的情况下,只是将密钥作为道具发送给父级也进行了重新渲染
2021-04-23 22:50:43
这也是我需要的。我很困惑,什么时候是key必需的,而只是setState我有一些依赖父母状态的孩子,但他们没有触发重新渲染......
2021-04-28 22:50:43
@dcsan 我认为原因是 React 使用引擎盖下的 key 属性来计算通过地图动态呈现的项目是否已被移动等。
2021-04-28 22:50:43

因为如果父级的 props 发生变化,子级不会重新渲染,但是如果它的 STATE 发生变化:)

你展示的是这个:https : //facebook.github.io/react/tips/communicate-between-components.html

它将通过 props 将数据从父级传递给子级,但那里没有重新渲染逻辑。

您需要为父级设置一些状态,然后在父级更改状态时重新渲染子级。这可能会有所帮助。 https://facebook.github.io/react/tips/expose-component-functions.html

你可以直接在源代码中看到它,这根本不是同一个过程
2021-04-17 22:50:43
state != props 你需要阅读更多相关信息。您不使用道具进行更新
2021-04-22 22:50:43
即使您更新组件,道具也不会更新,您传递的道具仍然存在。Flux 是另一个话题,是的 :)
2021-04-25 22:50:43
这是不正确的:reactjs.org/docs/react-component.html 如果 Child 和 Container 是组件,则会发生重新渲染。
2021-04-25 22:50:43
为什么 setState 会导致重新渲染但 forceUpdate 不会?也有点离题,但是当 props 从 redux 传递并且它的状态通过动作更新时,组件是如何更新的?
2021-05-03 22:50:43

我有同样的问题。这是我的解决方案,我不确定这是好的做法,如果不是,请告诉我:

state = {
  value: this.props.value
};

componentDidUpdate(prevProps) {
  if(prevProps.value !== this.props.value) {
    this.setState({value: this.props.value});
  }
}

UPD:现在你可以使用 React Hooks 做同样的事情:(仅当组件是一个函数时)

const [value, setValue] = useState(propName);
// This will launch only if propName value has chaged.
useEffect(() => { setValue(propName) }, [propName]);
我也在使用这种方法。
2021-04-15 22:50:43
当您在从父状态派生的子组件中有 props 时,此方法也适用
2021-04-17 22:50:43
您不需要也不应该将道具转换为子组件中的状态。直接使用道具即可。FunctionComponents它会自动更新,如果道具变化子组件。
2021-05-09 22:50:43
@vancy-pantscomponentDidUpdate在这种情况下进入 Child 组件。
2021-05-10 22:50:43
这绝对是正确的答案,更不用说最简单的了
2021-05-11 22:50:43

确认,添加一个 Key 有效。我浏览了文档以尝试了解原因。

React 希望在创建子组件时高效。如果它与另一个子组件相同,则不会呈现新组件,这会使页面加载速度更快。

添加一个 Key 会强制 React 渲染一个新组件,从而重置该新组件的 State。

https://reactjs.org/docs/reconciliation.html#recursing-on-children

当从functions创建 React 组件时useState

const [drawerState, setDrawerState] = useState(false);

const toggleDrawer = () => {
      // attempting to trigger re-render
      setDrawerState(!drawerState);
};

这确实工作

         <Drawer
            drawerState={drawerState}
            toggleDrawer={toggleDrawer}
         />

确实有效(添加密钥)

         <Drawer
            drawerState={drawerState}
            key={drawerState}
            toggleDrawer={toggleDrawer}
         />
这次真是万分感谢
2021-05-06 22:50:43