React - How to call a function whenever a state in react context is updated?

Viewed 824

I have a react application with lots of components. I am using React context api to manage the state in the application.

My react state in context looks like below.

{ key1: value1, key2: value2,  key3 : { key4 : { key5 : value5 } } }

So, it's basically a nested json.

Now, one of the keys let's say keys 3 is being updated from many of the components in react component tree. It could be updated by any component in the tree hierarchy.

So, here in this case, I want to call backend api whenever key3 changes. How do I do this in react?

EDIT 1:-

Below is how I have setup my context.

import React, { createContext, useEffect, useReducer } from "react";

import { reducer, initialState } from "./reducers";
import { useActions } from "./actions";

const AppContext = createContext(initialState);

const AppProvider = ({ children }: { children: any }): any => {
    const [state, dispatch] = useReducer(reducer, initialState);
    const actions = useActions(state, dispatch);

    useEffect(() => {
        console.log("Called ");
    }, [state.decision])

    return (
        <AppContext.Provider value={{ state, dispatch, actions }}>
            {children}
        </AppContext.Provider>
    );
};

export { AppContext, AppProvider };
2 Answers

useEffect must be helpfull.

Just add to the array of dependencies that part of the context that you want to monitor for changes.

useEffect(() => {
  //do something
}, [context.key3])

To call a function when a value changes use useEffect and useState hooks in react.

const [contextValue, setContextValue] = useState({})
useEffect(() => {
  //Call your function
}, [contextValue])

And while updating value:

setContextValue({key1:value1,...rest})
setContextValue({key2:value2,...rest})
setContextValue({key3:{},...rest})
setContextValue({key3:{key4:{},...rest1},...rest2})
setContextValue({key3:{key4:{key5:{},...rest1},...rest2},...rest3}) // and so on

This way, the single useEffect is triggered for all changes to the contextValue.

Demo Context:

const TestContext = React.createContext()

export function useTestContext() {
    return useContext(TestContext)
}

export function TestContextProvider({ children }) {
    const [contextValue, setContextValue] = useState({})
    
    useEffect(() => {
      //Call your function
    }, [contextValue])

    const value = {
        setContextValue,
        contextValue
    }

    return <TestContext.Provider value={value}>{children}</TestContext.Provider>
}
Related