在ReactJS中的兄弟姐妹组件之间传递事件方法

时间:2019-07-18 05:14:01

标签: reactjs react-router-dom

我在ReactJS中练习,在2个同级组件之间传递方法时遇到麻烦。我创建了具有3个组件的React应用程序:MainPage是父级,FirstPageSecondPage是两个子级。在FirstPage组件中有一个带有一些文本的标题,而SecondPage组件中有一个按钮。我的主要目标是将我在FirstPage中定义的更改标头方法通过MainPage组件传递给SecondPage组件,以便在单击按钮时触发事件方法。

我按照本教程https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17来构建我的应用程序。我还使用react-router-dom中的MainPage显示两个页面:一个用于FirstPage,另一个用于SecondPage

这是我的FirstPage组件:

import React from 'react'
class FirstPage extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            msg: 'First page'
        }

    }
    componentDidMount(){
        this.props.callBack(this.changeText.bind(this))
    }
    render(){
        return(
            <div className = "first">
                <h2>{this.state.msg}</h2>
            </div>
        )
    }
    changeText(){
         {/* event method I defined to change the header text*/}
        this.setState({msg: 'Text changed !!'})
        this.props.history.push('/first')
    }

}
export default FirstPage

MainPage组件:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import React from 'react'
import FirstPage from '../component/FirstPage'
import SecondPage from '../component/SecondPage'
class MainPage extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            func : null
        }
    }
    myCallBack(callFunc){
        this.setState({func: callFunc})
    }
    render(){
        return(
            <div className = "main">
                <Router>
                    <Switch>
                        <Route path = "/first" render = {(props) => <FirstPage  {...props} callBack = {this.myCallBack.bind(this)} />} />
                        <Route path = "/second" render = {(props) => <SecondPage  {...props} myFunc = {this.state.func}/>} />
                    </Switch>
                </Router>

            </div>
        )
    }
}
export default MainPage

在学习本教程之后,我在func状态内定义了属性MainPage,以存储FirstPage中的事件方法。 myCallBack方法用于更改状态的属性。然后,我使用FirstPage将该方法传递给callBack = {this.myCallBack.bind(this)}。因此,在FirstPage中,当调用this.props.callBack(this.changeText.bind(this))时,事件方法将存储为MainPage状态

最后是我的SecondPage伙伴:

import React from 'react'
class SecondPage extends React.Component{

    render(){
        return(
            <div className = "second">
                <h2>Second page</h2>
                <button onClick = {this.props.myFunc}> Click here to change</button>
            </div>
        )
    }
}
export default SecondPage

App.js:

import React from 'react'
import MainPage from './component/MainPage'

function App() {
  return (
    <div className = "App">
       <MainPage/>
    </div>

  );
}

export default App;

我只是通过道具将存储事件的this.state.func传递给SecondPage。我认为这应该可行:当我单击按钮时,React将重定向到“ FirstPage”并更改标题字段。但是实际上,当我单击时,什么也没有发生。谁能告诉我我做错了哪一部分?

1 个答案:

答案 0 :(得分:0)

嗨广。

为此,您可以采用以下一种可能的方法:

  • 对于父组件的两个同级之间的任何共享数据,我们基本上将共享数据放在最接近的父组件中,在本例中为MainPage

进一步:

  1. 您希望在FirstPage中显示并通过SecondPage进行更改的内容应位于父组件MainPage的状态下
  2. 将内容作为道具传递到FirstPage,例如content={this.state.content}
  3. 更改内容changeText的函数应该在MainPage内部,因为它将更改作为道具发送到FirstPage的特定状态
  4. 函数在被SecondPage调用时应更改MainPage的状态,并将其作为标头的内容传递给FirstPage

解决方案:

-第一页:

// Re-write as a functional component, because we won't be using lifecycle methods, thus, no need for it to be class component.
import React from 'react'

const FirstPage = (props) => (
  <div className = "first">
    <h2>{props.msg}</h2>
  </div>
);

export default FirstPage

-第二页:

// Re-write as a functional component, because we won't be using lifecycle methods, thus, no need for it to be class component.
import React from 'react'

const SecondPage = (props) => (
  <div className = "second">
    <h2>Second page</h2>
    <button onClick = {props.changeMsg}> Click here to change</button>
  </div>
)

export default SecondPage

-主页:

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import React from "react";
import FirstPage from "../component/FirstPage";
import SecondPage from "../component/SecondPage";
class MainPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: '', //added msg that is shown in FirstPage
    };
  }


  // Added the function changeMsg to modify msg value in the state by the button onClick event from SecondPage.
  changeMsg(){
      {/* event method I defined to change the header text*/}
    this.setState({ msg: 'Text changed !!' })
    this.props.history.push('/first')
  }

  // Cleared some un-used functions.
  // passed msg for FirstPage as a Prop
  // passed changeMsg to SecondPage as a Prop

  render() {
    return (
      <div className="main">
        <Router>
          <Switch>
            <Route
              path="/first"
              render={props => (
                <FirstPage {...props} msg={this.state.msg} />
              )}
            />
            <Route
              path="/second"
              render={props => (
                <SecondPage {...props} changeMsg={this.changeMsg.bind(this)} />
              )}
            />
          </Switch>
        </Router>
      </div>
    );
  }
}

export default MainPage;