簡體   English   中英

React:使用父級在兄弟組件之間傳遞數據

[英]React: Using parent to pass data between sibling components

我需要渲染widget這需要在設置從SettingsPanel ,並將它們傳遞到LayoutPanel (這會然后重新呈現本身基於更新的設置)。 我似乎無法找到一種“干凈”的方法來做到這一點。 這是我到目前為止所擁有的:

小部件.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>
    }
}

應用程序.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>
}

這樣,父級是轉儲消息代理,不必知道正在更改哪些特定設置的細節。 但當然,這不起作用,因為,a。 我被告知從道具設置狀態是一種反模式 b。 構造函數無論如何都無權訪問 this.props ,並且在其他地方(componentDidMount?)這樣做感覺不對。

我的第二個想法是去setProps為來自父母的孩子設置道具,但當然這已被棄用。

我該如何解決這個問題? 我可能可以重新構建它,所以這不是問題,但坦率地說,我只是想了解我缺少什么,或者解決此類問題的“反應”方式是什么。

這個問題與我遇到的同一問題類似,但我無法理解/應用公認的解決方案對我的問題的建議。

tldr; “如何讓父組件將狀態從一個子組件傳遞到另一個子組件,同時又不知道它到底傳遞了什么?”

從 props 設置狀態不一定是一種反模式。 從構造函數中的 props 初始化組件的狀態似乎是完全合理的。 這樣做並不會降低可測試性或可靠性。

您可以在構造函數中訪問 props,因為它們作為第一個參數傳遞。 你需要先調用super ,然后你可以做任何你想做的事情:

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

然后你可以繼續沿着你最初的道路前進。 另一個稍微復雜一點的選擇是使用像 Redux 這樣的狀態容器來為您處理狀態管理和轉換,但只有在您不介意向應用程序設置添加更多內容的額外學習和復雜性時才這樣做。

雖然 lukewestby 的答案是正確的,因為它解決了原始問題中的問題,但經過進一步思考后,我意識到這是一個錯誤的問題 - 即,這是一個架構問題,這就是我在實現時遇到問題的原因。

在這種情況下,數據流是 [data]-> App -> Widget -> Children。 “App”獲取數據,因此 App 擁有它。 小部件不應該能夠修改、處理對其不擁有的數據的更改。 因此,回調需要傳遞給祖父(App),而不是父(Widget)。 這就是我最終做的。

應用程序.js

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

小部件.js

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

這樣做的好處是設置有一個單一的真實來源,由所有者(應用程序)維護。 在最初的建議中,如果在稍后由App獲取設置已更改,則內部組件將不會收到它(這解釋了為什么 React 文檔聲稱 props 的設置狀態是一種反模式)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM