最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React useState value in Context API always use initial value instead of updated value - Stack Overflow

programmeradmin4浏览0评论

I'm using Context API to store global value like userId to share between ponents across entire application.

Here's what the context.js looks like:

import React, { useState } from 'react';

const AppContext = React.createContext({
    date: new Date(),
    userId: null,
    groupId: null,
    setAppContext: () => {},
});

export const AppContextProvider = (props) => {
    const initState = {
        date: new Date(),
        userId: null,
        groupId: null,
        setAppContext: (appContext) => {
            console.log(state); // this line always log initial state value after first update
            setState({ ...state, ...appContext });
        },
    }
    const [state, setState] = useState(initState);
    return (
        <AppContext.Provider value={state}>
            {props.children}
        </AppContext.Provider>
    )
}

export default AppContext;

Basically I'm trying to use one big context to hold all value that I use together and access them in child ponents like this:

// access value and the setter
const { userId, setAppContext } = useContext(AppContext);

// setting value
setAppContext({
    userId: newUserId,
});

The problem is, "state" variable in the setter function doesn't seems to update and when I try to set new value like above, other values get overwrite with its initial value (e.g. userId get update but the rest return to null), which I guess I must do something wrong and I still have no idea.

Any advice would be much appreciated.

I'm using Context API to store global value like userId to share between ponents across entire application.

Here's what the context.js looks like:

import React, { useState } from 'react';

const AppContext = React.createContext({
    date: new Date(),
    userId: null,
    groupId: null,
    setAppContext: () => {},
});

export const AppContextProvider = (props) => {
    const initState = {
        date: new Date(),
        userId: null,
        groupId: null,
        setAppContext: (appContext) => {
            console.log(state); // this line always log initial state value after first update
            setState({ ...state, ...appContext });
        },
    }
    const [state, setState] = useState(initState);
    return (
        <AppContext.Provider value={state}>
            {props.children}
        </AppContext.Provider>
    )
}

export default AppContext;

Basically I'm trying to use one big context to hold all value that I use together and access them in child ponents like this:

// access value and the setter
const { userId, setAppContext } = useContext(AppContext);

// setting value
setAppContext({
    userId: newUserId,
});

The problem is, "state" variable in the setter function doesn't seems to update and when I try to set new value like above, other values get overwrite with its initial value (e.g. userId get update but the rest return to null), which I guess I must do something wrong and I still have no idea.

Any advice would be much appreciated.

Share asked Jun 20, 2020 at 12:53 DANKESTDANKEST 411 gold badge1 silver badge3 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

In this case:

const AppContext = React.createContext({
    date: new Date(),
    userId: null,
    groupId: null,
    setAppContext: () => {},
});

setAppContext is just a function, it is not from React API.

In order to change state, and make React to be aware of its change, you need to use any setter function from React API.

Like setter function returned from useState().

See similar question here.

So, in your case, to solve it you need to pass a real setter:

const initState = {
  date: new Date(),
  userId: null,
  groupId: null,
};

const AppContext = React.createContext();

export const AppContextProvider = (props) => {
  const [state, setState] = useState(initState);

  const setAppContext = (appContext) => {
    console.log(state);
    setState({ ...state, ...appContext });
  };

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

export default AppContext;

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论