React context api, pass data to parent

With react context API how do I send my data/state back up to parent component?

For example:

-  Component 1 (App.js) [contextOneProvider]
  -  Component 2  
    -  Component 3  ==> Need a state from child component 7
      -  Component 4
        -  Component 5 [contextOneConsumer, getting state from component 1]
          -  Component 6 
            -  Component 7 ==> Need to send a state to parent component 3
              -  Component 8 [contextOneConsumer, getting state from component 1]

So currently I have created one context which the provider of context one is used on component 1 and consumer of context one is used on component 5 and component 8.

To avoid prop drilling, should I create another new separate context and use the new context’s provider on component 3 and consumer on component 7, so that child component 7 can use a method from parent component 3 to send the state back up, is this the only way or are there any other better ways ? (If I do it without context api, I’ll need to send method down to each component until I reach component 7, which I don’t want)

This is my first time using react context API

thanks

You can’t pass data directly to a parent in React, so you do what you do with any other component & pass a callback function. Which you can just be one of the values stored in context, same as any other value. I mean, probably just put both in the top provider component, it saves faffing on

Sorry, I still don’t quite get it, so do you mean doing something like below example:

Parent component 3

const componentThree = () => {
  const [id, setId] = useState('');
  
  // Create function, use it in child component 7  
  const getId = (id) => {
    // Get id back from child component 7
    setId(id);
  };
  return (
    <div>
      <ComponentFour getId={getId} />
    </div>
  );
}

component 4

const componentFour = ({getId}) => {
  return (
    <div>
      <ComponentFive getId={getId} />
    </div>
  );
}

component 5

const componentFive = ({getId}) => {
  return (
    <div>
      <ComponentSix getId={getId} />
    </div>
  );
}

component 6

const componentSix = ({getId}) => {
  return (
    <div>
      <ComponentSeven getId={getId} />
    </div>
  );
}

Child component 7

const componentSeven = ({getId}) => {

  const handleOnClick = () => {
    const id = 4;
    // Which use here to send id back up to parent component 3
    getId(id);
  };

  return (
    <div>
      <button onClick={handleOnClick} ></button>
    </div>
  );
}

Do you mean something like above? but if I do the above way, I am still prop drilling and component 4, component 5 and component 6 doesn’t really need getId function, it exist just so that I can pass down to next child component until I reach child component 7.

or do you mean create another new context, and use the new context’s provider in parent component 3 and new context’s consumer in child component 7?

You have two options with context, you can either create a second context provider (Component 3) and make Component 7 the consumer, or you can put it all into Component 1. It would hold the state of Component 3, and provide a function for Component 7 to update that state.

What @jsdisco says, but it’s quite hard to see what you’re trying to do. I would expect something like

const MyContext = React.createContext();

const MyProvider = (props) => {
  const [someState, setSomeState] = React.useState("HELLO");

  return (<MyContext.Provider value={{ someState, setSomeState }}>{props.children}</MyContext.Provider>);
}

Then

const Component7 = () => {
  const { setSomeState } = React.useContext(MyContext);

  return (
    <div>
      <button onClick={() => setSomeState("Button was clicked in 7")}>Press me</button>
    </div>
  );
}

const Component3 = () => {
  const { someState } = React.useContext(MyContext);

  return (
    <div>
      { /* This will be "Button was clicked in 7" when the button was clicked in 7 */ }
      <p>{ someState }</p> 
    </div>
  );
}
1 Like

Hi @DanCouper and @jsdisco thank you both so much for the help, really appreciate it!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.