Denis2310
Denis2310

Reputation: 1208

ReactJs Context not updated, values always default

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>
  );

Upvotes: 4

Views: 1853

Answers (2)

Ben Stickley
Ben Stickley

Reputation: 2120

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.

Upvotes: 2

Andrea Costanzo
Andrea Costanzo

Reputation: 2215

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.

Upvotes: 2

Related Questions