如何在REACT中从另一个同级或导入的组件更新同级组件的状态

时间:2018-07-20 00:04:49

标签: javascript reactjs

嗨,我最近才开始学习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; 

3 个答案:

答案 0 :(得分:5)

您需要根据自己的情况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组件。

答案 1 :(得分: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>
        )
    }
}

答案 2 :(得分:2)

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