Robolisk
Robolisk

Reputation: 1792

Detect if a button is pressed in a different component to run a function in another function react

Less detail: How do I call a function within another component based on a parent components state change due to another child component changing it?

I have a simple app component that renders a Header component (buttons, navbar etc) and a Grid component that displays a grid. Within this grid are nodes that are selected. I removed a lot of the functionality of this component to better isolate my dilemma:

import React from 'react';

import Header from './layout/Header.js';
import Grid from './interactive/PathFinderGrid.js';
import './App.css';


export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      isClearSelected : false,
    }
  }
  HandleButtonClick = event => {
    if (event.target.name === "isClearSelected") {
      this.setState({isClearSelected : !this.state.isClearSelected});
    }
  }
  ToggleClearComplete = () => {
    this.setState({isClearSelected : false});

  }
  render() {
    return (
      <div className="App">
        <React.Fragment>
          <Header
            HandleButtonClick = {this.HandleButtonClick}
          />
        </React.Fragment>
        <Grid
          isClearSelected = {this.state.isClearSelected}
          ToggleClearComplete = {this.ToggleClearComplete}
        />
      </div>
    );
  }
}

When the Clear button from within Header is selected, I can get and validate that it was clicked within my App component.

Inside my grid, I set up the grid with nodes within the constructor and I also have a ClearGrid method that regenerates my grid. This is a very very simplistic example of what my grid is (it's actually much more complex):

import React from 'react';

export default class Grid extends React.Component {
  constructor(props){
    super(props);
    const newNodeArray = [];
    // begin creating the 2D array representing the grid
    for (let row = 0; row < 10; row++) { 
      const newRow = []; // initialize 1D array
      for (let col = 0; col 20; col++) {
        newRow.push([]); // initalize 2D array
      }
      newNodeArray.push(newRow); // push into newNodeArray
    } 
    this.state = {
      nodeSize : nodeSize,
      nodeArray : newNodeArray,
    }
  }
  DisplayNodes = () => {
   // display node array
  }
  render() {
    return (
      <div id="grid-wrapper">
        {this.DisplayNodes()}
      </div>
    )
  }
}

I'm confused how within Grid would I detect that the App state regarding isClearSelected has changed and run a function within Grid to reset the state.

Upvotes: 0

Views: 1362

Answers (3)

Chris B.
Chris B.

Reputation: 5763

You are already passing isClearSelected to the Grid component as a prop. You can simply listen to it for changes and "react" accordingly. Since you're still using class components (which on a side note are slowly being deprecated), you could hook into the componentDidUpdate method and check if the prop has changed:

componentDidUpdate(prevProps, prevState) {
  if (this.props.isClearSelected !== prevProps.isClearSelected) {
   // The prop changed and I should do a thing
}
}

Upvotes: 2

Dillan Wilding
Dillan Wilding

Reputation: 1111

To be able to use App's state inside Grid, pass a property on props into Grid which you are already doing with the isClearSelected. Then in Grid, you can reference the isClearSelected property by using props.isClearSelected.

Upvotes: 1

Jay Lane
Jay Lane

Reputation: 1401

you should use a lifecycle method, so when the state changes and is passed down via props to the Grid component you can execute the clearGrid method. [https://reactjs.org/docs/react-component.html#componentdidupdate][1]

Upvotes: 1

Related Questions