reactjsreact-context

How to assign complex objects to context in React?


I am trying to set data of context.

context :

import React from "react";
const AppContext = React.createContext<IContext>({} as IContext);
export default AppContext;

In App.tsx file I fill with default values :

function App() {

    const [ContextData, setContextData] = useState({
        profile: {
            firstName: "",
            lastName: ""
        },
        package: {
            name:"",
            code: "",
            version: "",
            totalPumpCount: 0
        }
    });

    return (
        <AppContext.Provider value={{ ContextData, setContextData }}>
            <BrowserRouter>
                <Routes>
                    <Route path="login" element={<Login />} />
                    <Route path="/DailyWorkPlan" element={<DailyWorkPlan />} />
                    <Route path="/Setting" element={<Setting />} />
                    <Route path="/Report" element={<Report />} />
                    <Route path="/About" element={<About />} />
                    <Route path="/PumpsStatus" element={<PumpsStatus />} />
                    <Route path="/SensorsStatus" element={<SensorsStatus />} />
                    <Route path="/PackageCommands" element={<PackageCommands />} />
                    <Route path="/PumpsService" element={<PumpsService />} />
                    <Route path="/DrivesService" element={<DrivesService />} />
                    <Route path="/DailyFlow" element={<DailyFlow />} />
                    <Route path="/DataBase" element={<DataBase />} />
                    <Route path="/" element={<Home />} />
                    <Route path="*" element={<NotFound />} />
                </Routes>
            </BrowserRouter>
        </AppContext.Provider>
    );
}

export default App;

and then in another component, I try to fetch data and set it to context :

 const { ContextData, setContextData } = React.useContext(AppContext);
 //fill user context
 useMount(() => {

    fetch('/home/GetContext')
        .then(response => response.json())
        .then((response) => {
            setContextData({
                profile: {
                    firstName: response.data?.firstName,
                    lastName: response.data?.lastName,
                    id: 0,
                    userId: '',
                    mobile: '',
                    allowSendSmsOnOff: false,
                    allowSendSmsFault: false,
                    allowSendSmsSensor: false,
                    allowSendSmsDriveConnection: false,
                    allowSendSmsLoginFailed: false,
                    isActive: false
                },
                package: {
                    totalPumpCount: response.data?.totalPumpCount,
                    name: response.data?.name,
                    code: response.data?.code,
                    version: response.data?.version,
                }

            });



        }).then(() => {
            console.log(ContextData);
        })
        .catch((error) => {
            toast.error('/home/GetContext : ' + error.message);
        });
});
    

interface IContext {
    profile: IProfile,
    package: IPackage,
    setContextData(arg0: IContext): IContext
}

The fetched data is not set currently!!!

What is the problem?


Solution

  • The shape of your IContextData does not match what you provide with value={{ ContextData, setContextData }}.

    You'd want value={{ ...ContextData, setContextData }} to destructure the state atom (profile, package) into the context value.