【问题标题】:React: Using parent to pass data between sibling componentsReact:使用父级在兄弟组件之间传递数据
【发布时间】:2016-02-06 20:49:00
【问题描述】:

我需要渲染一个widget,它接受来自SettingsPanel 的设置并将它们传递给LayoutPanel(然后它将根据更新的设置重新渲染自身)。我似乎无法想出一个“干净”的方法来做到这一点。到目前为止,这是我所拥有的:

Widget.js

class Widget extends Component {
    handleSettingsChange() {
        //need to let layout know of change
    }

    render() {
        <div>
            <SettingsPanel
                onSettingsChange={handleSettingsChange}
                initialSettings={this.props.settings}
            />
            <Layout
                data={ this.props.data}
            />
        </div>
    }
}

App.js

const settings = {
    hideImages: true,
    itemsPerPage: 5
}
<Widget settings={ settings } data={ data } />

我的第一个想法是,在 Widget 中,我可以做到

constructor() {
    super()
    this.setState({ settings: this.props.settings });
}
handleSettingsChange(data) {
    //Assuming data is of the form {changedProperty: value}
    this.setState({ settings: Object.assign({}, this.state.settings, data) });
}
render() {
    <div>
        <SettingsPanel
            onSettingsChange={handleSettingsChange}
            initialSettings={this.props.settings}
        />
        <Layout
            data={ this.props.data}
            settings={ this.state.settings }
        />
    </div>
}

这样,父级是转储消息代理,不必知道正在更改的特定设置的细节。但当然,这行不通,因为, 一个。我被告知从道具设置状态是一种反模式 湾。构造函数无论如何都无法访问 this.props,并且在 else-where (componentDidMount?) 中执行它感觉不对。

我的第二个想法是去setProps 为来自父母的孩子设置道具,但当然不推荐使用。

我该如何解决这个问题?我可能会重新设计它,所以这不是问题,但坦率地说,我只是想了解我缺少什么,或者解决此类问题的“反应”方式是什么。

This question 与我遇到的相同问题相似,但我无法理解/应用已接受的解决方案对我的问题提出的建议。

tldr; “我怎样才能让父组件将状态从一个子组件传递给另一个子组件,同时又不知道它到底传递了什么?”

【问题讨论】:

    标签: javascript reactjs components


    【解决方案1】:

    虽然 lukewestby 的回答是正确的,因为它解决了原始问题中的问题,但经过进一步思考,我意识到这是一个错误的问题 - 即,这是一个架构问题,这就是为什么我在实施时遇到问题.

    在这种情况下,数据流是 [data]-> App -> Widget -> Children。 “App”获取数据,因此 App 拥有它。小部件不应该能够修改、处理对它不拥有的数据的更改。因此,回调需要传递给祖父母(App),而不是父(Widget)。这就是我最终要做的。

    App.js

     constructor() {
       this.state = { settings: { hideImages: true } };
     }
     handleSettingsChange(data) {
       this.setState({ settings: data });
     }
     render() {
       <Widget settings={ this.state.settings } 
          onSettingsChange={ this.handleSettingsChange }
        />
    } 
    

    Widget.js

    handleDisplaySettingsChange(data) {
        this.props.onSettingsChange(data);
    }
    render() {
        return (
            <div>
                <SettingsPanel
                    onSettingsChange={ this.handleDisplaySettingsChange }
                />
                <Layout
                    {...this.props.settings }
                />
            </div>
        );
    }
    

    这样做的好处是设置的唯一真实来源,由所有者(应用程序)维护。在最初的建议中,如果稍后通过 App 获取设置已更改,内部组件将不会接收它(这解释了为什么 React 文档声称从 props 设置状态是一种反模式)

    【讨论】:

    • 不错!容器组件模式的伟大应用:)
    • 感谢您告诉我它叫什么! :)
    【解决方案2】:

    从道具设置状态不一定是反模式。从构造函数中的 props 初始化组件的状态似乎是完全合理的。这样做不会大大降低可测试性或可靠性。

    您可以在构造函数中访问道具,因为它们作为第一个参数传递。你需要先打电话给super,然后你可以做任何你想做的事:

    class Widget extends React.Component {
      constructor(props) {
        super(props);
        this.setState({ settings: props.settings });
      }
    }
    

    然后你可以继续你原来的路径。另一个稍微复杂一点的选择是使用像 Redux 这样的状态容器来为您处理状态管理和转换,但只有在您不介意向应用设置添加更多内容的额外学习和复杂性时才这样做。

    【讨论】:

      猜你喜欢
      • 2019-12-30
      • 2018-07-27
      • 2021-12-26
      • 2022-09-28
      • 2015-06-19
      • 2020-12-18
      • 2018-10-03
      • 1970-01-01
      • 2019-03-24
      相关资源
      最近更新 更多