Search code examples
javascriptreactjsreact-contextuse-context

Using context API (React.js) to change only a particular key in state object


I am using context API in react for managing state. For this I have created a file AppContext.js where I have created context and Provider:

import { useState, createContext } from "react";

export const AppContext = createContext();

export const AppProvider = (props) => {
   const [appdata, setAppdata] = useState({
      data1: "this is data1",
      data2: "this is data2",
   });

   return (
      <AppContext.Provider value={[appdata, setAppdata]}>
         {props.children}
      </AppContext.Provider>
   );
};

I have imported this Provider in the parent component of the app i.e App.js. Also I have wrapped the <AppChild/> component in the Provider.

import AppChild from "./AppChild";
import { AppProvider } from "./AppContext";

const App = () => {
   return (
      <AppProvider>
         <div className="App">hello</div>
         <AppChild />
      </AppProvider>
   );
};

export default App;

Now from AppChild component, I only needed to update the data1 key of my state. For this I have created a button with a onClick through which I will be changing my state. I have used to following code in AppChild.js for this:

import { useContext } from "react";
import { AppContext } from "./AppContext";

const AppChild = () => {
   const [appdata, setAppdata] = useContext(AppContext);
   return (
      <div>
         <h3 style={{ color: "red" }}>Data for Appchild: {appdata.data1}</h3>
         <button
            onClick={() =>
               setAppdata((prev) => {
                  prev.data1 = "updated data1";
                  return prev;
               })
            }
         >
            click to change
         </button>
      </div>
   );
};

export default AppChild;

But when I click the button, the text inside the <h3> block is not changing. Although when I change the whole state by passing the whole object directly to setAppdata as shown below, new code

This way the state updates successfully. Why is the first method not working where I only wanted to change the data1 key?


Solution

  • You are updating state in wrong way so it is not working. This is how you should update state

    <button
     onClick={() =>
       setAppdata((prevState) => ({
         ...prevState,
         data1: "Your New Data"
            }))
          }
        >
            click to change
          </button>