javascript - 当父状态改变时强制子组件更新

标签 javascript reactjs react-redux

我有一个MyList获取项目的组件,允许过滤和排序。该组件已在应用程序的其他部分使用,并且运行良好。它使用渲染 Prop 来渲染项目,因此它接受 renderItem类型函数的 prop。

现在我正在构建一个简单的列表,以允许使用上述组件进行项目选择,并且我正在检查渲染属性 renderItem 中的选定状态方法。问题是当我更改 MySelectableList 的状态时MyList组件不会更新,因为它的 props 没有改变(它始终是相同的绑定(bind)函数 renderProp )。现在我用 this.renderItem = this.renderItem.bind(this); 强制渲染 child 。但我不喜欢它,我知道我可以用 ref 更新子组件但我也不喜欢。

是否有更好的方法来强制子组件在父状态发生变化时渲染?我做错了什么吗?

完整代码MySelectableList :

class MySelectableList extend Component {
    constructor (props) {
        super(props);

        this.state = {
            selectedItems: [],
        };
        this.renderItem = this.renderItem.bind(this);
        this.toggle = this.toggle.bind(this);
        this.isSelected = this.isSelected.bind(this);
    }

    toggle (item) {
        const newItems = this.state.selectedItems.slice(0);
        const index = newItems.indexOf(item.uuid);
        if (index === -1) {
            newItems.push(item.uuid);
        } else {
            newItems.splice(index, 1);
        }
        this.setState({ selectedItems: newItems });
        // Force MyList to re-render by tricking react that it's different
        this.renderItem = this.renderItem.bind(this);
    }

    isSelected (item) {
        return this.state.selectedItems.includes(item.uuid);
    }

    renderItem (item) {
        return (<MySelectableItem
            key={ item.uuid }
            item={ item }
            toggle={ this.toggle }
            selected={ this.isSelected(item) } />);
    }

    render () {
        return (
            <div>
                ...
                <MyList renderItem={ this.renderItem } />
                ...
            </div>
        );
    }
}

提前致谢。

编辑

MyList组件使用 connect 连接到 redux store 。我发现connectMyList 的原因组件缺少渲染,仅使用“vanilla” react 组件即可正常工作。

我在这个codesandbox中重现了这个问题:https://codesandbox.io/s/0mov14nmmp

最佳答案

既然您询问如何以更友好的方式做到这一点

更好的方法是:

render () {
        return (
            <div>
                <MyList {...whateeverExtraPropsyouWantToPass}>
                   <MySelectableItem
                       key={ item.uuid }
                       item={ item }
                       toggle={ this.toggle }
                       selected={ this.isSelected(item) } />
                </MyList>
            </div>
        );

然后你的 MyList 将如下所示:

render () {
        return (
            <div>
               ...//your other MyList code
               ...
               {this.props.children}
            </div>
        );

这看起来更具可读性,更易于维护且易于调试。但我相信这对你来说都是显而易见的。既然您询问了 react 友好的方式,这是您可以做到的最 react 友好的方式。

我不会建议不必要的、显式地尝试渲染任何组件。直到且除非这是唯一的方法,但您的组件中并非如此。

关于javascript - 当父状态改变时强制子组件更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48387872/

相关文章:

javascript - flask +d3.js : Passing multiple datasets to html

reactjs - Webpack:postcss-loader 忽略配置文件

javascript - 如果存在 js/ajax 导航功能,则停止链接导航

javascript - cakephp - js文件中图像的路径

javascript - 如何知道 anchor 位于文本或图像上?

reactjs - 在 mobx 存储中更改状态时 Ant-Design Table 不呈现

javascript - 如何在 appendchild 方法 javascript 或 reactjs 中使用文件夹路径中的 svg?

reactjs - 如何使用redux工具包动态生成reducer和action类型?

typescript - 如何在页面刷新时正确补充 NextJS 中的 Redux 状态?

javascript - 如何使用 react-redux 中的 reducer 状态的值更新组件的状态?