为什么在下面的伪代码示例中,当容器更改foo.bar时,子不重新呈现?

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

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

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

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


当前回答

你可以使用componentWillReceiveProps:

componentWillReceiveProps({bar}) {
    this.setState({...this.state, bar})
}

这要归功于Josh Lunsford

其他回答

当从函数和useState创建React组件时。

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}
         />

在我的例子中,我正在更新传递给组件的加载状态。在按钮内的道具。加载是通过预期的(从假切换为真),但显示旋转器没有更新的三元。

我尝试添加一个键,添加一个状态,更新useEffect()等,但没有其他答案工作。

对我有效的是改变这一点:

setLoading(true);
handleOtherCPUHeavyCode();

:

setLoading(true);
setTimeout(() => { handleOtherCPUHeavyCode() }, 1)

我认为这是因为handleOtherCPUHeavyCode中的进程非常繁重和密集,所以应用程序会冻结一秒钟左右。添加1ms超时允许加载布尔值更新,然后繁重的代码函数可以完成它的工作。

你应该使用setState函数。如果不是,无论如何使用forceUpdate, state都不会保存您的更改。

Container {
    handleEvent= () => { // use arrow function
        //this.props.foo.bar = 123
        //You should use setState to set value like this:
        this.setState({foo: {bar: 123}});
    };

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

你的代码似乎无效。我不能测试这段代码。

在子组件connect方法的mapStateToProps中定义更改的道具。

function mapStateToProps(state) {
  return {
    chanelList: state.messaging.chanelList,
  };
}

export default connect(mapStateToProps)(ChannelItem);

在我的例子中,channelList的通道被更新了,所以我在mapStateToProps中添加了chanelList

我的案例涉及在props对象上有多个属性,并且需要在更改其中任何一个时重新渲染Child。 上面提供的解决方案是有效的,但为每个方案添加一个密钥变得乏味和肮脏(想象一下有15个……)如果有人面临这个问题,你可能会发现stringify props对象很有用:

<Child
    key={JSON.stringify(props)}
/>

这样,对props上的每个属性的每次更改都会触发Child组件的重新呈现。

希望这能帮到别人。