简体   繁体   中英

Fire component method from another component on ReactJs

I have this components:

class DashTopNav extends React.Component {
  constructor(props) {
    super(props);
  }
  render(){
    return(<button></button>);
  }
}
class FltBox extends React.Component {
  constructor(props) {
    super(props);
  }

  methodToFired(){
  }
}

class XDashBoard extends React.Component {
    constructor(props) {
    super(props);
  }
  render(){
    return(<div className="XDashBoard">
        <DashTopNav onClick={call methodToFired on FltBox}  />
        <FltBox />
    </div>);
  }
}

I want to call a Method on FltBox (methodToFired) with a button on DashTopNav, but I cant find the way to call a function on a child component from another child component.

This is most likely not what you want to be doing.

It seems to me like you want to extract the methodToFired from the FltBox component into your XDashBoard component since it seems to be a generic type of method and pass that down as a prop to your DashTopNav component or use the Flux pattern to fire an action from your DashTopNav that your FltBox then responds to.

Your example code is too barebones in order to make a correct assumption but below is a working refactor that would most likely suit you better.

class DashTopNav extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return(<button {...this.props}>Button</button>);
  }
}

class XDashBoard extends React.Component {
  constructor(props) {
    super(props);
  }

  methodToFired (e) {
    console.log('fired');
  }

  render() {
    return(
      <div className="XDashBoard">
        <DashTopNav onClick={this.methodToFired} />
      </div>
    );
  }
}

With React, you shouldn't try to access another component method arbitrarily. Basically, React is not design that way. React components react to changes in their props and states, so you can control them by chaging their props and states.

In you example, you can pass a class method from the parent component to DashTopNav.onClick and change the FltBox props inside that function, forcing FltBox to re-render and update when the user click DashTopNav . If the final result of FltBox can be derived directly from that props change, then the render function is enough, if you need to perform a side effect as a reaction to the props change, then you can use React lifecycle methods like didComponentUpdate .

For example:

class DashTopNav extends React.Component {
  constructor(props) {
    super(props);
  }

  render(){
    return(<button></button>);
  }
}

class FltBox extends React.Component {
  constructor(props) {
    super(props);
  }

  didComponentUpdate() {
    // Handle navButtonClick update 
  }
}

class XDashBoard extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
       navButtonClick: false 
    };
  }

  handleNavClick = () => {
     this.setState({navButtonClick: true});
  }

  render(){
    const {navButtonClick} = this.state;

    return(
      <div className="XDashBoard">
        <DashTopNav onClick={this.handleNavClick}  />
        <FltBox navButtonClick />
      </div>
    );
  }
}

You can use refs

By using refs we can access DOM nodes or React elements created in the render method in this example we will use refs to access the element that holds the methodToFired in FltBox component we will use div element thus we can access methodToFired .

then we will use that ref to the div element and pass it to whichever component we want in our case DashTopNav as a prop which is onClick={this.parentClickHandler}

 class FltBox extends React.Component { constructor(props) { super(props); } methodToFired(){ alert('Fired from FltBox') } // here we use ref to access to the div element render() { return (<div ref={div => this.div = div}></div>); } } class DashTopNav extends React.Component { constructor(props) { super(props); } render(){ return ( <button onClick={this.props.onClick}>Submit</button> ); } } class XDashBoard extends React.Component { constructor(props) { super(props); this.parentClickHandler = this.parentClickHandler.bind(this) } parentClickHandler() { this.mydiv.methodToFired(); } render(){ return(<div className="XDashBoard"> <DashTopNav onClick={this.parentClickHandler} /> <FltBox ref={div => this.mydiv = div}/> </div>); } } ReactDOM.render(<XDashBoard />, document.querySelector("#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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM