【问题标题】:How to update the state of a sibling component from another sibling or imported component in REACT如何在 REACT 中从另一个同级或导入的组件更新同级组件的状态
【发布时间】:2018-07-20 00:04:49
【问题描述】:

嗨,我最近刚开始学习 ReactJS,一直在玩导入和导出功能,例如这是应用程序的结构,3 个单独的文件父级和 2 个子级;如何将状态从 InputArea 导出到 DisplayArea?

父组件

import React, { Component } from 'react';
import DisplayArea from './DisplayArea';
import InputArea from './InputArea';

class App extends Component {
  render() {
    return (
      <div id="wrapper" className="App">
        <DisplayArea />
        <InputArea />
      </div>
    );
  }
}

export default App;

子 1 组件

import React, { Component } from 'react';
import InputArea from './InputArea';

class DisplayArea extends Component {
  constructor(props){
    super(props);
  }

    render() {
      return (
        <div className="column">
            <div className="col-body">
                <div id="preview">{ How to display contents here? }</div>
            </div>
        </div>
      );
    }
  }

export default DisplayArea;  

子 2 组件

import React, { Component } from 'react';

class InputArea extends Component {
    constructor(props){
      super(props);
      this.state = {
        content: ''
      }
      this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e){
      e.preventDefault();
      this.setState({
        content: e.target.value
      })
    }

    render() {
      return (
        <div className="column">

            <div className="col-body">
                <textarea id="editor" placeholder="Enter text here" onChange={this.handleChange}></textarea>
            </div>
        </div>
      );
    }
  }

export default InputArea; 

【问题讨论】:

  • 这是一个带有react的基本概念。除非你使用像 Redux 这样的状态管理,否则传递 props 是一种单向方法。我已经在这里回答了这个==> stackoverflow.com/questions/47858242/…您应该尽量避免像您正在做的那样使用从一个孩子到另一个侧面的道具,要么是第二个孩子的下一个孩子,要么使用状态管理。无论您的选择如何,您都需要创建一个“updateParent”函数,您可以在我之前的回答中找到该函数。

标签: javascript reactjs


【解决方案1】:

根据您的情况,您需要lift your state up。第二个选项是@Gavin Thomas 在评论中建议的。但是如果没有 Redux,你可以这样做:

const InputArea = (props) => {
  const handleChange = (e) => props.handleInputValue(e.target.value);

  return (
    <div className="column">
      <div className="col-body">
        <textarea
          id="editor"
          placeholder="Enter text here"
          onChange={handleChange}
        ></textarea>
      </div>
    </div>
  );
};

const DisplayArea = (props) => (
  <div className="column">
    <div className="col-body">
      <div id="preview">{props.inputValue}</div>
    </div>
  </div>
);

class App extends React.Component {
  state = {
    inputValue: "Initial Value",
  };

  handleInputValue = (inputValue) => this.setState({ inputValue });

  render() {
    return (
      <div id="wrapper" className="App">
        <DisplayArea inputValue={this.state.inputValue} />
        <InputArea handleInputValue={this.handleInputValue} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

在这里,我们将输入值状态保存在父组件中,即 App。我们将回调函数传递给 InputArea 并使用此回调函数更改父组件的状态。然后我们将此状态传递给我们的 DisplayArea 组件。

【讨论】:

  • 不客气。是的,在消化 React 之后肯定会选择 Redux。
【解决方案2】:

以下是代码的相关部分。基本上将liftState 方法传递给InputArea 组件,它实际上会在调用时更新App 的状态。然后将content 作为道具传递给DisplayArea

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            content: ""
        };
    }
    liftState = state => {
        this.setState(state);
    }
    render() {
        return (
            <div className="App">
                <InputArea liftState={this.liftState}/>
                <DisplayArea content={this.state.content}/>
            </div>
        );
    }
}

class InputArea extends Component {
    handleChange(event) {
        this.props.liftState({content: event.target.value});
    }
}

class DisplayArea extends Component {
    render() {
        return (
            <div className="column">
                <div className="col-body">
                    <div id="preview">{this.props.content}</div>
                </div>
            </div>
        )
    }
}

【讨论】:

    【解决方案3】:

    React.js 文档说 (Lifting State Up):

    通常,多个组件需要反映相同的变化数据。我们 建议将共享状态提升到最接近的公共状态 祖宗……

    例子:

    // Parent component which contains shared state
    class Parent extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          child1Value: 0,
          child2Value: 0,
        }
    
        this.handleChild1Click = this.handleChild1Click.bind(this);
        this.handleChild2Click = this.handleChild2Click.bind(this);
      }
    
      handleChild1Click(nextValue) {
        this.setState({ child1Value: nextValue });
      }
    
      handleChild2Click(nextValue) {
        this.setState({ child2Value: nextValue });
      }
    
      render() {
        return (
          <div>
            <Child
              value={this.state.child2Value}
              onClick={this.handleChild1Click}
            />
            <Child
              value={this.state.child1Value}
              onClick={this.handleChild2Click}
            />
          </div>
        )
      }
    }
    
    
    class Child extends Component {
      constructor(props) {
        super(props);
    
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        this.props.onClick(this.props.value + 1);
      }
    
      render() {
        return (
          <div>
            <p>Value of my sibling: {this.props.value}</p>
            <button onClick={this.onClick}></button>
          </div>
        )
      }
    }
    

    【讨论】:

    • 这个答案很酷也很正确,但我想每个人都会喜欢一些代码!
    • @JimmyAdaro 我提供了一个例子。我希望它对你来说更清楚。考虑使用一种在组件之间共享状态的新方法 - reactjs.org/docs/hooks-intro.html
    猜你喜欢
    • 1970-01-01
    • 2018-04-03
    • 2022-09-28
    • 2019-02-26
    • 2017-10-06
    • 2016-05-12
    • 2023-01-03
    • 2022-01-19
    • 2020-07-01
    相关资源
    最近更新 更多