592

My structure looks as follows:

Component 1

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5

Component 3

Component 3 should display some data depending on state of Component 5.

Since props are immutable, I can't simply save its state in Component 1 and forward it, right? And yes, I've read about Redux, but I don't want to use it. I hope that it's possible to solve it just with react. Am I wrong?

6
  • 52
    super-easy: pass the parent-setState-Function via property to the child-component: <MyChildComponent setState={p=>{this.setState(p)}} /> In the child-component call it via this.props.setState({myObj,...}); Commented May 8, 2018 at 21:47
  • 1
    <MyChildComponent setState={(s,c)=>{this.setState(s, c)}} /> if your going to use this hack make sure you support the callback.
    – Barkermn01
    Commented Apr 10, 2019 at 14:50
  • 17
    Passing a callback to set the parent's state is a really bad practice that could lead to maintenance problems. It breaks encapsulation and it makes components 2 4 and 5 tightly coupled to 1. If walk this path then you won't be able to reuse any of these child components elsewhere. It's better you have specific props so child components could trigger events whenever something happens, then the parent component would handle that event properly.
    – Pato Loco
    Commented Oct 4, 2019 at 13:51
  • 1
    @MarcelEnnix, why the curly brackets around this.setState(p) ? I tried without them and it appears to work (I'm very new to React)
    – Biganon
    Commented Apr 10, 2020 at 15:12
  • 4
    @Biganon Hmm. You are right. Sorry for that 2 extra chars :-) Maybe its because i like Curly Brackets so much. I have a Shirt printed with this Statement^^ Commented Apr 12, 2020 at 6:48

26 Answers 26

924

For child-parent communication you should pass a function setting the state from parent to child, like this


class Parent extends React.Component {
  constructor(props) {
    super(props)

    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      someVar: 'some value'
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {this.props.handler}/ >
  }
}

This way the child can update the parent's state with the call of a function passed with props.

But you will have to rethink your components' structure, because as I understand components 5 and 3 are not related.

One possible solution is to wrap them in a higher level component which will contain the state of both component 1 and 3. This component will set the lower level state through props.

22
  • 8
    why do you need this.handler = this.handler.bind(this) and not just the handler function that sets the state?
    – chemook78
    Commented Feb 24, 2017 at 17:49
  • 62
    @chemook78 in ES6 React classes methods do not auto-bind to class. So if we don't add this.handler = this.handler.bind(this) in constructor, this inside the handler function will reference the function closure, not the class. If don't want to bind all your functions in constructor, there are two more ways to deal with this using arrow functions. You could just write the click handler as onClick={()=> this.setState(...)}, or you could use property initialisers together with arrow functions as described here babeljs.io/blog/2015/06/07/react-on-es6-plus under "Arrow functions"
    – Ivan
    Commented Feb 24, 2017 at 20:54
  • 2
    Here's an example of this in action: plnkr.co/edit/tGWecotmktae8zjS5yEr?p=preview
    – Tamb
    Commented Jun 1, 2017 at 2:03
  • 6
    That all makes sense, why e.preventDefault ? and does that require jquery? Commented Jul 3, 2017 at 22:21
  • 1
    Quick question, does this disallow the assignment of a local state within the child? Commented May 2, 2018 at 17:29
148

This is how to do it with the new useState hook.

Method - Pass the state changer function as a props to the child component and do whatever you want to do with the function:

import React, {useState} from 'react';

const ParentComponent = () => {
  const[state, setState]=useState('');
  
  return(
    <ChildComponent stateChanger={setState} />
  )
}


const ChildComponent = ({stateChanger, ...rest}) => {
  return(
    <button onClick={() => stateChanger('New data')}></button>
  )
}
9
  • 4
    Nice modern example Commented Feb 16, 2021 at 22:15
  • 1
    Thanks. @mylesthe.dev Commented Oct 8, 2021 at 18:22
  • for some strange reason., Iam getting stateChanger (setState) is not a function. I used same exact code Commented Feb 13, 2022 at 13:45
  • The props you passed to stateChanger is not a function. Or you have done anything wrong. Share your code. Commented Feb 13, 2022 at 15:59
  • Thanks @moshfiqrony, quick question for you if you don't mind. Inside ChildComponent, the onClick event handler is assigned a callback function instead of just directly invoking stateChanger(). Is that because information is being passed from Child --> Parent and changing a state property on Parent? I'm trying to settle a longstanding question of when I should use callback functions versus just directly invoking them. Any insight would be appreciated. Thanks!
    – Vayl
    Commented Apr 4, 2022 at 10:18
67

I found the following working solution to pass the onClick function argument from the child to the parent component:

Version with passing a method()

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate = this.props.handleToUpdate;
        return (<div><button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component {

    constructor(props) {
        super(props);
        var handleToUpdate = this.handleToUpdate.bind(this);
        var arg1 = '';
    }

    handleToUpdate(someArg){
        alert('We pass argument from Child to Parent: ' + someArg);
        this.setState({arg1:someArg});
    }

    render() {
        var handleToUpdate = this.handleToUpdate;

        return (<div>
                    <ChildB handleToUpdate = {handleToUpdate.bind(this)} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <ParentA />,
        document.querySelector("#demo")
    );
}

Look at JSFiddle

Version with passing an Arrow function

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate = this.props.handleToUpdate;
        return (<div>
          <button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component {
    constructor(props) {
        super(props);
    }

    handleToUpdate = (someArg) => {
            alert('We pass argument from Child to Parent: ' + someArg);
    }

    render() {
        return (<div>
            <ChildB handleToUpdate = {this.handleToUpdate} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <ParentA />,
        document.querySelector("#demo")
    );
}

Look at JSFiddle

6
  • 1
    This one is good! could you explain this piece: <ChildB handleToUpdate = {handleToUpdate.bind(this)} /> Why had to bind again ?
    – Dane
    Commented Oct 14, 2017 at 13:46
  • 1
    @Dane - you have to bind the context of this to be the parent so that when this is called inside the child, this refers to the parent's state and not the child's. This is closure at its finest!
    – HighHopes
    Commented Mar 14, 2018 at 21:37
  • @Casey but aren't we doing that in the constructor ? And isn't that enough ??
    – Dane
    Commented Mar 15, 2018 at 4:18
  • You're totally right! I missed that. Yes, if you did it in the constructor already then you're good to go!
    – HighHopes
    Commented Mar 15, 2018 at 4:20
  • You're a legend mate! This'll keep components nicely self contained without having to be forced to create parent components to handle the state exchanges
    – adamj
    Commented Jul 1, 2018 at 0:47
24

I want to thank the most upvoted answer for giving me the idea of my own problem basically the variation of it with arrow function and passing param from child component:

 class Parent extends React.Component {
  constructor(props) {
    super(props)
    // without bind, replaced by arrow func below
  }

  handler = (val) => {
    this.setState({
      someVar: val
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {() => this.props.handler('the passing value')}/ >
  }
}

Hope it helps someone.

4
  • whats special about the arrow function over direct call ? Commented May 20, 2019 at 5:50
  • @AshishKamble the this in arrow functions refers to the parent's context (i.e. Parent class).
    – CPHPython
    Commented Jun 11, 2019 at 13:14
  • 2
    This is a duplicate answer. You could add a comment to the accepted answer and mention about this experimental feature to use arrow function in class.
    – Arashsoft
    Commented Aug 28, 2019 at 15:47
  • What is (was) the most upvoted answer? Can you be more specific? The most upvoted answer may change over time. Commented May 21, 2021 at 15:23
13

I like the answer regarding passing functions around. It's a very handy technique.

On the flip side you can also achieve this using pub/sub or using a variant, a dispatcher, as Flux does. The theory is super simple. Have component 5 dispatch a message which component 3 is listening for. Component 3 then updates its state which triggers the re-render. This requires stateful components, which, depending on your viewpoint, may or may not be an anti-pattern. I'm against them personally and would rather that something else is listening for dispatches and changes state from the very top-down (Redux does this, but it adds additional terminology).

import { Dispatcher } from 'flux'
import { Component } from 'React'

const dispatcher = new Dispatcher()

// Component 3
// Some methods, such as constructor, omitted for brevity
class StatefulParent extends Component {
  state = {
    text: 'foo'
  } 

  componentDidMount() {
    dispatcher.register( dispatch => {
      if ( dispatch.type === 'change' ) {
        this.setState({ text: 'bar' })
      }
    }
  }

  render() {
    return <h1>{ this.state.text }</h1>
  }
}

// Click handler
const onClick = event => {
  dispatcher.dispatch({
    type: 'change'
  })
}

// Component 5 in your example
const StatelessChild = props => {
  return <button onClick={ onClick }>Click me</button> 
}

The dispatcher bundles with Flux is very simple. It simply registers callbacks and invokes them when any dispatch occurs, passing through the contents on the dispatch (in the above terse example there is no payload with the dispatch, simply a message id). You could adapt this to traditional pub/sub (e.g., using the EventEmitter from events, or some other version) very easily if that makes more sense to you.

2
  • 1
    My Reacts components are "running" in browser like in an official tutorial (facebook.github.io/react/docs/tutorial.html) I tried to include Flux with browserify, but browser says, that Dispatcher is not found :( Commented Feb 21, 2016 at 20:06
  • 3
    The syntax I used was ES2016 module syntax which requires transpilation (I use Babel, but there are others, the babelify transform can be used with browserify), it transpiles to var Dispatcher = require( 'flux' ).Dispatcher Commented Feb 22, 2016 at 8:44
10

I found the following working solution to pass the onClick function argument from the child to the parent component with a parameter:

Parent class:

class Parent extends React.Component {
constructor(props) {
    super(props)

    // Bind the this context to the handler function
    this.handler = this.handler.bind(this);

    // Set some state
    this.state = {
        messageShown: false
    };
}

// This method will be sent to the child component
handler(param1) {
console.log(param1);
    this.setState({
        messageShown: true
    });
}

// Render the child component and set the action property with the handler as value
render() {
    return <Child action={this.handler} />
}}

Child class:

class Child extends React.Component {
render() {
    return (
        <div>
            {/* The button will execute the handler function set by the parent component */}
            <Button onClick={this.props.action.bind(this,param1)} />
        </div>
    )
} }
3
  • 2
    Can anyone tell whether that's an acceptable solution (particularly interested in passing the parameter as suggested).
    – ilans
    Commented Nov 26, 2017 at 6:52
  • param1 is just display on console not get assign it always assigns true Commented Jun 12, 2019 at 8:31
  • I can't speak to the quality of the solution, but this successfully passes the param for me.
    – James
    Commented Mar 15, 2020 at 4:29
8

Most of the answers given previously are for React.Component-based designs. If you are using useState in the recent upgrades of the React library, then follow this answer.

6

Whenever you require to communicate between a child to the parent at any level down, then it's better to make use of context. In the parent component define the context that can be invoked by the child, such as:

In the parent component, in your case component 3,

static childContextTypes = {
    parentMethod: React.PropTypes.func.isRequired
};

getChildContext() {
    return {
        parentMethod: (parameter_from_child) => this.parentMethod(parameter_from_child)
    };
}

parentMethod(parameter_from_child){
    // Update the state with parameter_from_child
}

Now in the child component (component 5 in your case), just tell this component that it wants to use the context of its parent.

static contextTypes = {
    parentMethod: React.PropTypes.func.isRequired
};

render() {
    return(
        <TouchableHighlight
            onPress = {() => this.context.parentMethod(new_state_value)}
            underlayColor='gray' >

            <Text> update state in parent component </Text>

        </TouchableHighlight>
)}

You can find the Demo project in this GitHub repository.

1
  • I cant able to understand this answer, can you explain more about it Commented Jun 12, 2019 at 4:34
6

It seems that we can only pass data from parent to child as React promotes unidirectional data flow, but to make the parent update itself when something happens in its "child component", we generally use what is called a "callback function".

We pass the function defined in the parent to the child as "props" and call that function from the child triggering it in the parent component.


class Parent extends React.Component {
  handler = (Value_Passed_From_SubChild) => {
    console.log("Parent got triggered when a grandchild button was clicked");
    console.log("Parent->Child->SubChild");
    console.log(Value_Passed_From_SubChild);
  }
  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <SubChild handler = {this.props.handler}/ >
  }
}

class SubChild extends React.Component {
  constructor(props){
   super(props);
   this.state = {
      somethingImp : [1,2,3,4]
   }
  }
  render() {
     return <button onClick = {this.props.handler(this.state.somethingImp)}>Clickme<button/>
  }
}
React.render(<Parent />,document.getElementById('app'));

 HTML
 ----
 <div id="app"></div>

In this example we can make data pass from sub childchildparent by passing function to its direct child.

5

I've used a top rated answer from this page many times, but while learning React, I've found a better way to do that, without binding and without an inline function inside props.

Just look here:

class Parent extends React.Component {

  constructor() {
    super();
    this.state = {
      someVar: value
    }
  }

  handleChange = (someValue) => {
    this.setState({someVar: someValue})
  }

  render() {
    return <Child handler={this.handleChange} />
  }

}

export const Child = ({handler}) => {
  return <Button onClick={handler} />
}

The key is in an arrow function:

handleChange = (someValue) => {
  this.setState({someVar: someValue})
}

You can read more here.

0
5

If this same scenario is not spread everywhere you can use React's context, especially if you don't want to introduce all the overhead that state management libraries introduce. Plus, it's easier to learn. But be careful; you could overuse it and start writing bad code. Basically you define a Container component (that will hold and keep that piece of state for you) making all the components interested in writing/reading that piece of data to/from its children (not necessarily direct children).

Context - React

You could also use a plain React properly instead.

<Component5 onSomethingHappenedIn5={this.props.doSomethingAbout5} />

Pass doSomethingAbout5 up to Component 1:

<Component1>
    <Component2 onSomethingHappenedIn5={somethingAbout5 => this.setState({somethingAbout5})}/>
    <Component5 propThatDependsOn5={this.state.somethingAbout5}/>
<Component1/>

If this is a common problem, you should starting thinking moving the whole state of the application to somewhere else. You have a few options, the most common are:

Basically, instead of managing the application state in your component you send commands when something happens to get the state updated. Components pull the state from this container as well so all the data is centralized. This doesn't mean you can't use local state any more, but that's a more advanced topic.

5

Simply pass the parent's setState function via props to the child component.

function ParentComp() {
  const [searchValue, setSearchValue] = useState("");
  return <SearchBox setSearchValue={setSearchValue} searchValue={searchValue} />;
}

then in child component:

function SearchBox({ searchValue, setSearchValue }) {
  return (
        <input
          id="search-post"
          type="text"
          value={searchValue}
          onChange={(e) => setSearchValue(e.target.value)}
          placeholder="Search Blogs ..."
        />
    )
}

A second example to handle click from child component:

// We've below function and component in parent component
const clickHandler = (val) => {
  alert(`httpRequest sent. \nValue Received: ${val}`);
};

// JSX
<HttpRequest clickHandler={clickHandler} />

this is how you get function from parent component then pass a value and fire clickHandler through it.

function HttpRequest({ clickHandler }) {
  const [content, setContent] = useState("initialState");

  return (
    <button onClick={() => clickHandler(content)}>
      Send Request
    </button>
  );
}

export default HttpRequest;
4

We can create ParentComponent and with a handleInputChange method to update the ParentComponent state. Import the ChildComponent and we pass two props from the parent to the child component i.e., the handleInputChange function and count.

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

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.state = {
      count: '',
    };
  }

  handleInputChange(e) {
    const { value, name } = e.target;
    this.setState({ [name]: value });
  }

  render() {
    const { count } = this.state;
    return (
      <ChildComponent count={count} handleInputChange={this.handleInputChange} />
    );
  }
}

Now we create the ChildComponent file and save it as ChildComponent.jsx. This component is stateless because the child component doesn't have a state. We use the prop-types library for props type checking.

import React from 'react';
import { func, number } from 'prop-types';

const ChildComponent = ({ handleInputChange, count }) => (
  <input onChange={handleInputChange} value={count} name="count" />
);

ChildComponent.propTypes = {
  count: number,
  handleInputChange: func.isRequired,
};

ChildComponent.defaultProps = {
  count: 0,
};

export default ChildComponent;
1
  • How does this work when the child has a child that affects the prop of its parent?
    – Bobort
    Commented Jan 28, 2019 at 17:22
4

If you want to update the parent component,

class ParentComponent extends React.Component {
    constructor(props){
        super(props);
        this.state = {
           page: 0
        }
    }

    handler(val){
        console.log(val) // 1
    }

    render(){
        return (
            <ChildComponent onChange={this.handler} />
        )
    }
}


class ChildComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
             page: 1
        };
    }

    someMethod = (page) => {
        this.setState({ page: page });
        this.props.onChange(page)
    }

    render() {
        return (
            <Button
                onClick={() => this.someMethod()}
            > Click
        </Button>
      )
   }
}

Here onChange is an attribute with "handler" method bound to its instance. We passed the method handler to the Child class component, to receive via the onChange property in its props argument.

The attribute onChange will be set in a props object like this:

props = {
    onChange: this.handler
}

and passed to the child component.

So the child component can access the value of name in the props object like this props.onChange.

It's done through the use of render props.

Now the child component has a button “Click” with an onclick event set to call the handler method passed to it via onChange in its props argument object. So now this.props.onChange in the child holds the output method in the parent class.

Reference and credits: Bits and Pieces

1
  • Sorry.. for delay, Here onChange is an attribute with "handler" method bound to it's instance. we passed the method handler to the Child class component, to receive via onChange property in its props argument. The attribute onChange will be set in a props object like this: props ={ onChange : this.handler } and passed to the child component So the Child component can access the value of name in the props object like this props.onChange Its done through the use of render props. Reference and credits: [blog.bitsrc.io/… Commented Aug 15, 2019 at 15:01
4

We can set the parent state from a child component by passing a function into the child component as props as below:

class Parent extends React.Component{
    state = { term : ''}

     onInputChange = (event) => {
         this.setState({term: event.target.value});
     }

     onFormSubmit = (event) => {
         event.preventDefault();
         this.props.onFormSubmit(this.state.term);
     }

     render(){
         return (
             <Child onInputChange={this.onInputChange} onFormSubmit=
                {this.onFormSubmit} />
         )
     }
}


class Child extends React.Component{

     render(){
         return (
             <div className="search-bar ui segment">
                 <form className="ui form" onSubmit={this.props.onFormSubmit}>
                     <div class="field">
                         <label>Search Video</label>
                         <input type="text" value={this.state.term} onChange=
                             {this.props.onInputChange} />
                     </div>
                 </form>
             </div>
         )
     }
}

This way, the child will update the parent state onInputChange and onFormSubmit are props passed from parents. This can be called from event listeners in the child, hence the state will get updated there.

4

Parent Component

 function Parent() {
        const [value, setValue] = React.useState("");

        function handleChange(newValue) {
          setValue(newValue);
        }

        // We pass a callback to Child
        return <Child value={value} onChange={handleChange} />;
    }

Child Component

    function Child(props) {
         function handleChange(event) {
             // Here, we invoke the callback with the new value
             props.onChange(event.target.value);
         }
  
         return <input value={props.value} onChange={handleChange} />
    }
3

To set state of parent in the child you can use callback.

const Child = ({handleClick}) => (
    <button on click={() => handleClick('some vale')}>change value</button>
)

const parent = () => {
    const [value, setValue] = useState(null)

    return <Child handleClick={setValue} />
}

In your structure it seems Components 1 an 3 are brothers. So you has 3 options:

1- Put the state into the parent of them(not recommended for 4 layer parent-child).

2- Use useContext and useRducer(or useState) together.

3- Use state managers like redux, mobx ...

2

Here is a short snippet to get two ways binding data.

The counter show the value from the parent and is updated from the child

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.handler = this.handler.bind(this)
     this.state = {
      count: 0
     }
  }

  handler() {
    this.setState({
      count: this.state.count + 1
    })
  }

  render() {
    return <Child handler={this.handler} count={this.state.count} />
  }
}

class Child extends React.Component {
  render() {
    return <button onClick={this.props.handler}>Count {this.props.count}</button>
  }
}

ReactDOM.render(<Parent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

2

This is the way I do it:

type ParentProps = {}
type ParentState = { someValue: number }
class Parent extends React.Component<ParentProps, ParentState> {
    constructor(props: ParentProps) {
        super(props)
        this.state = { someValue: 0 }

        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(value: number) {
        this.setState({...this.state, someValue: value})
    }

    render() {
        return <div>
            <Child changeFunction={this.handleChange} defaultValue={this.state.someValue} />
            <p>Value: {this.state.someValue}</p>
        </div>
    }
}

type ChildProps = { defaultValue: number, changeFunction: (value: number) => void}
type ChildState = { anotherValue: number }
class Child extends React.Component<ChildProps, ChildState> {
    constructor(props: ChildProps) {
        super(props)
        this.state = { anotherValue: this.props.defaultValue }

        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(value: number) {
        this.setState({...this.state, anotherValue: value})
        this.props.changeFunction(value)
    }

    render() {
        return <div>
            <input onChange={event => this.handleChange(Number(event.target.value))} type='number' value={this.state.anotherValue}/>
        </div>
    }
}
1
  • What is the idea here? Can someone elaborate? Commented May 21, 2021 at 18:14
2

As per your question, I understand that you need to display some conditional data in Component 3 which is based on the state of Component 5. Approach:

  1. The state of Component 3 will hold a variable to check whether Component 5's state has that data
  2. An arrow function which will change Component 3's state variable.
  3. Passing an arrow function to Component 5 with props.
  4. Component 5 has an arrow function which will change Component 3's state variable
  5. An arrow function of Component 5 called on loading itself

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Class Component3 extends React.Component {
    state = {
        someData = true
    }

    checkForData = (result) => {
        this.setState({someData : result})
    }

    render() {
        if(this.state.someData) {
            return(
                <Component5 hasData = {this.checkForData} />
                //Other Data
            );
        }
        else {
            return(
                //Other Data
            );
        }
    }
}

export default Component3;

class Component5 extends React.Component {
    state = {
        dataValue = "XYZ"
    }
    checkForData = () => {
        if(this.state.dataValue === "XYZ") {
            this.props.hasData(true);
        }
        else {
            this.props.hasData(false);
        }
    }
    render() {
        return(
            <div onLoad = {this.checkForData}>
                //Conditional Data
            </div>
        );
    }
}
export default Component5;

1

This seem to work for me

Parent:

...

const [open, setOpen] = React.useState(false);

const handleDrawerClose = () => {
    setOpen(false);
  };

...

return (
                <PrimaryNavigationAccordion           
                  handleDrawerClose={handleDrawerClose}               
                />
              );

Child:

...

export default function PrimaryNavigationAccordion({
  props,
  handleDrawerClose,
})

...

<Link
                    to={menuItem.url}
                    component={RouterLink}
                    color="inherit"
                    underline="hover"
                    onClick={() => handleDrawerClose()}
                  >
                    {menuItem.label}
                  </Link>
1

You can do it by passing a reference for the parent to child, as:

  1. Having a parent component A in A.js with a method updateAState
  2. Having a child component B in B.js
  3. Having a wrapper function that renders <A><B></B></A> in C.js
  4. In C.js you can use useRef as following:
import React, { useRef } from "react";

export default function C()
{
  const parentARef = useRef();
  const handleChildBClick = () => parentARef.current.updateAState();
  return (
    <A ref={parentARef}>
      <B onClick={handleChildBClick}>
      </B>
    </A>
  );
}

Guidance Reference: https://stackoverflow.com/a/56496607/1770571

1

Using functional components and hooks:

const Parent = (props) => {
  const [Vari, setVari] = useState('');

  const handler = () => {
    setvari('value');
  }

  return <Child handler={handler} />
}

this approach eliminate the need for a constructor and binding, making the code cleaner and more concise.

0

try this

//PARENT
import App_next from "./App_next";

export default class App extends React.Component {

    state = {
        content: null
    };
    render() {

        if( this.state.content ){

            return <App_next handler={this}/>;
        }
        return (
            <View style={styles.container}>
                <Text>Open up App.js to start working on your app!</Text>
                <Button onPress={() => {this.setState({'content': 'next'})}} title="NEXT"/>
                <StatusBar style="auto"/>
            </View>
        );
    }
}

//CHILD
export default class App_next extends React.Component {

    render() {

        return (
            <View style={styles.container}>
                <Text>THIS</Text>
                <Button onPress={() => {this.props.handler.setState({'content': null})}} title="BACK"/>
                <StatusBar style="auto"/>
            </View>
        );
    }
}
-2

Data cannot be passed from child to parent in React. Data must be passed from parent to child. In this case, you can use either the built-in Context API or a third-party state management solution such as Redux, Mobx, or Apollo GraphQL. However, if your app structure is too small, you can store your data in your parent element and then send it to your child via prop drilling. But if your project is larger, it will be messy.

-5
<Footer 
  action={()=>this.setState({showChart: true})}
/>

<footer className="row">
    <button type="button" onClick={this.props.action}>Edit</button>
  {console.log(this.props)}
</footer>

Try this example to write inline setState, it avoids creating another function.
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.