4
  • I have parent wrapper component and I added react context inside it.
  • Inside that wrapper component I also have useEffect() hook which I use to fetch some values from API and then set these values to context.
  • Inside my child component which is using context, values for context are always default ones. When I check in browser react tools it seems that values for context are updated but when I test it with console.log it always returns default ones.

Parent component which has context inside:

...
export const CorporateContext = createContext({corporateId: null, corporateRole: null, corporateAdmin: null, corporateSuperAdmin: null});

export const CorporateWrapper = ({ apiBaseUrl, children }) => {
    const [corporateContextDefaults, setCorporateContextDefaults] = 
    useState({corporateId: null, corporateRole: null, corporateAdmin: null, corporateSuperAdmin: null});

    useEffect(() => {
        (async () => {
            try {
                const json = await fetchCorporateUserDetails(apiBaseUrl);

                if (json.success !== true) {
                    console.log(json.message);
                  } else {
                    console.log(json.data) // <-- TESTED RESPONSE FROM API
                    setCorporateContextDefaults(json.data); // <-- UPDATE CONTEXT VALUES HOOK AND PASS IT BELOW TO CONTEXT PROVIDER
                  }

               
                } catch (e) {
                    console.log(e.message);
                }
            })();
    }, []);

    return (
        <CorporateContext.Provider value={corporateContextDefaults}>
        {children}
        </CorporateContext.Provider>
    );
};

export default CorporateWrapper;

Child component which is using that context:

const CorporateSettingsPage: React.FC<CorporateSettingsPageProps> = ({
  apiBaseUrl,
  campusBaseUrl,
  ecomBaseUrl,
}: CorporateSettingsPageProps) => {
  const corporateContext = useContext(CorporateContext);

  console.log('corporate context is:');    //<-- ALWAYS RETURNS DEFAULT VALUES
  console.log(corporateContext);


  useEffect(() => {
    (async () => {
      try {
        const json = await fetchCorporateSettings(apiBaseUrl, 
corporateContext.corporateId);
  ...
    })();
  }, [corporateContext]);

  return (
      <CorporateWrapper apiBaseUrl={apiBaseUrl}> // <--- PARENT COMPONENT WITH CONTEXT INSIDE
        <div>
           ...
           <SomeOtherComponent />   // <-- CONTEXT IS CORRECT HERE AND UPDATED VALUES ARE SHOWN
        </div>
      </CorporateWrapper>
  );
7
  • 1
    try adding a useEffect hook in the parent component that logs corporateContextDefaults every time it changes. In this way we exclude that the problem is not in the state but in the context. If it doesn't log anything or it logs the default value in the last update the problem is in the state Commented Oct 1, 2021 at 20:44
  • I tried. first console.log are default values and then second are values from api so correct. I updated my question. There is one more child component which have correct context values inside it, so context works fine there. Maybe my whole "Child Component" is not actually a child because inside that page I am wrapping page content inside wrapper component Commented Oct 1, 2021 at 20:51
  • 1
    If you are using your context in a non-child then you found your issue. Since your component won't be a child of the provider you defined, it will never receive your value Commented Oct 1, 2021 at 20:54
  • Now when I added that wrapper inside app.js file and remove it from file above, it works fine. Is that correct place just to wrap everything in app.js? Commented Oct 1, 2021 at 20:54
  • 1
    Context can be placed everywhere, the important thing is that you respect the fact that the consumer is a child of the component. Obviously putting every context inside your app.js can become soon difficult to maintain, so always try to thing "is this the correct place?". Maybe you will notice that is necessary to create another component Commented Oct 1, 2021 at 20:56

2 Answers 2

2

Try to do these things:

  1. First ensure that the state is correctly updating. This should be enough to debug:
useEffect(()=>{
console.log(corporateContextDefaults);
},[corporateContextDefaults])
  1. If the state is updating correctly the problem is in your Provider->Consumer relation.

Verify that your consumer is a child of the providing component.

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

2 Comments

Yep, that is the thing -> If the state is updating correctly the problem is in your Provider->Consumer relation. Wrong relation
@Denis2310 I was just pointing out a possible procedure for future readers that might read in future, now I will answer above
2

React docs state: "All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes.". Your CorporateSettingsPage component won't be able to useContext(CorporateContext) because it's not a descendant of CorporateWrapper whereas SomeOtherComponent which is a descendant will be able to.

Comments

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.