0

I've been studying react and developing an app, but i got a problem using context. In one component I create the context and provide its value, but when I try to use the current value of context in another component, I have the default value. Code:

Component One:

export const OwnerInformationContext = React.createContext({})

function NameChoose() {

   ...
   const [ownerInformation,setOwnerInformation] = useState({})
 
    function onpressSubmitButton(e : FormEvent) {
        e.preventDefault();
        ...
        setOwnerInformation({name:'name',roomId:'id',owner:'true'})
    }

    return(
        <div className="page-container">
            <OwnerInformationContext.Provider value={ownerInformation} />
            ...
                <form onSubmit={onpressSubmitButton}>
                    ...
                </form>
            ...
    );
}

export default NameChoose;

So when i try to use by:

import { OwnerInformationContext } from '../NameChoose/index'

    function ComponentTwo(){

    const consumeOwnerContext = useContext(OwnerInformationContext)

    useEffect(() => {
                console.log(consumeOwnerContext)
        }, [])

    return <h1>test</h1>

    }

I got the default value provide in component one, that's {}.

1
  • 1
    Is ComponentTwo rendered inside the <Provide... tag? that part is not clear. Commented Oct 10, 2020 at 22:21

3 Answers 3

1

It looks like your context provider is not actually wrapping any components, as it has a self-closing tag:

<OwnerInformationContext.Provider value={ownerInformation} />

It should be:

<OwnerInformationContext.Provider value={ownerInformation}>
  {/* Your child components here will have access to the context */}
</OwnerInformationContext.Provider>

Sign up to request clarification or add additional context in comments.

1 Comment

Good catch on the closing tag. My first thought was if it's showing the default value then it's probably not in a Provider.
0

You are using useEffect as ComponentDidMount meaning only at start(mount) the value will be console log.

you should give consumeOwnerContext as a dependency to useEffect like this

useEffect(()=>{
  console.log(consumeOwnerContext);
},[consumeOwnerContext]);

And rename consumeOwnerContext to consumeOwnerValue, because you are getting the value out of the context using useContext.

After that when you will click on submit button you should have ComponentTwo console log it.

4 Comments

is ComponentTwo a descendent of the Provider? try console log it in the function itself and not in useEffect
also can you provide a not working example? say in code sandbox?
I edited the code; componentTwo is another component, i'm just using the useContext to acess the context
It slipped my eyes but also what @zzzachzzz says is true you should wrap all of your consumers in the Provider
0
import React, { useState, useEffect, useContext } from "react";

export const OwnerInformationContext = React.createContext({});

function ComponentTwo() {
const consumeOwnerContext = useContext(OwnerInformationContext);

useEffect(() => {
// You are using consumeOwnerContext inside useEffect, in that case add
// it as dependency if you want to see the updated consumeOwnerContext value

console.log(consumeOwnerContext);
}, [consumeOwnerContext]);

return <div>test</div>;
};

function NameChoose() {
const [ownerInformation, setOwnerInformation] = useState({});

function onpressSubmitButton(e) {
e.preventDefault();
setOwnerInformation({ name: "name",roomId: "id",owner: "true",});
}

return (
// The 'OwnerInformationContext.Provider' has to wrap the component 
// that will use its context value. In your case, ComponentTwo 
// has to be a child of NameChoose.


<OwnerInformationContext.Provider value={ownerInformation}>
<div className="page-container">
 <form onSubmit={onpressSubmitButton}>
   <button type="submit">Submit</button>
 </form>
</div>
<ComponentTwo />
</OwnerInformationContext.Provider>
);
}

export default NameChoose;

4 Comments

pls, add explanation of what u did
ComponentTwo has to be a child of the NameChoose component, which allows you to have access to the OwnerInformationContext values. Which is what I did, ComponetTwo renders within the opening and closing tags of OwnerInformationContext.Provider. Inside useEffect if you do not add consumeOwnerContext as a dependency within the square buckets, you won't see changes when the submit button is clicked. Adding the consumeOwnerContext within the square brackets means rerun the code within useEffect if the consumeOwnerContext value changes. I hope it makes sense.
but, what if i want to Component Two, that's in another file, receive the info from the provider, but don't render in the provider's page ?
Copy ComponentTwo code to a new file and then import the file into NameChoose component.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.