a-dawg
a-dawg

Reputation: 1263

React context not shared between components

I use a react context between 2 components, however when I set the value this context in the child filtersBar component, it does not update or useffect in the second child map component.

contextprovider

const SearchContext = createContext();

const SearchContextProvider = ({children}) => {
const [contextValue, setContextValue] = useState(null);            
    return (
    <SearchContext.Provider value={[contextValue, setContextValue]}>
        {children}
    </SearchContext.Provider>
);

index.js

 <SearchContextProvider>
    <FiltersBar/>
      <Map/>
    </SearchContextProvider>

Filtersbar.js

const FiltersBar = () => {
        const [searchContext,setSearchContext] = useContext(SearchContext);
        const [searchLocationResult, setsearchLocationResult] = useState(null);
        const [inputSearchLocation, setinputSearchLocation] = useState("");
  
 useEffect(() => {
// stuff
                 searchContext.autocompleteLocation = [46.6, 8.5]
              setSearchContext(searchContext)

        }, [searchLocationResult, inputSearchLocation]);

Map.js

const Map = () => {
  
    const [searchContext, setSearchContext] = useContext(SearchContext);


    useEffect(() => {
      console.log("use effect map"+JSON.stringify(searchContext))
    }, [searchContext]);

I never see this use effect map console log message. What am I missing?

Upvotes: 1

Views: 827

Answers (3)

Vengleab SO
Vengleab SO

Reputation: 814

React hook is a bit different with React state in Class component. React hook consider state changes only if it's new object, u should create new object when you update the state.

You can update the useEffect of FiltersBar as below: Filtersbar.js

const FiltersBar = () => {
        ...
 useEffect(() => {
// stuff
    setSearchContext({...searchContext, autocompleteLocation: [46.6, 8.5]})

}, [searchLocationResult, inputSearchLocation]);

Upvotes: 0

Nicholas Tower
Nicholas Tower

Reputation: 84902

If the code you've shown is an accurate representation of your real code, the problem is that you're mutating state, not creating a new one. When you set state, react does a === between the state before and the state after. It sees that they're the same object, so it thinks nothing has changed, and it does nothing.

So instead of this:

searchContext.autocompleteLocation = [46.6, 8.5]
setSearchContext(searchContext)

Do this:

const newState = {
  ...searchContext,
  autocompleteLocation: [46.6, 8.5]
}
setSearchContext(newState);

Upvotes: 1

Anh Le
Anh Le

Reputation: 290

Because of this

useEffect(() => {
  /// stuff
  setSearchContext(searchContext) // ----> here
}, [searchLocationResult, inputSearchLocation]);

searchContext never changes. it always null, you awlays set null to setSearchContext function. Maybe you only get first console.log like use effect mapnull when reload or component init

Upvotes: 0

Related Questions