简体   繁体   English

如何使用 react hooks useEffect/useReducer + useContext 优雅地更改 ts 中上下文的值?

[英]How to use react hooks useEffect/useReducer + useContext to change context's value in ts gracefully?

As a React starter, I'm trying to achieve state management in my React app, and use useContext to share login status between components.作为一个React初学者,我试图在我的React应用程序中实现 state 管理,并使用useContext在组件之间共享登录状态。

I started learning and read this question: >https://stackoverflow.com/questions/54738681/how-to-change-the-value-of-a-context-with-usecontext?r=SearchResults.我开始学习并阅读了这个问题:>https://stackoverflow.com/questions/54738681/how-to-change-the-value-of-a-context-with-usecontext?r=SearchResults。

I tried what the answer told me -- use useEffect to update the context's value:我尝试了答案告诉我的内容——使用useEffect更新上下文的值:

const initContext: GlobalContext = {
  login: false,
}

export const globalContext = React.createContext(null)

function App() { 

  return <globalContext.Provider value={useState(initContext)}>
    {useRoutes(router)}
  </globalContext.Provider>
}

But when I use ts to do the same thing, I got error但是当我用ts做同样的事情时,我得到了错误

Type '[GlobalContext, Dispatch<SetStateAction>]' is not assignable to type 'null'.类型“[GlobalContext, Dispatch<SetStateAction>]”不可分配给类型“null”。

So I tried another way:所以我尝试了另一种方式:

const initContext: GlobalContext = {
  login: false,
}

export const globalContext = React.createContext(useState(initContext))

function App() { 
return <globalContext.Provider value={useState(initContext)}>
    {useRoutes(router)}
  </globalContext.Provider>
}

then I got another error:然后我得到另一个错误:

React Hook "useState" cannot be called at the top level.无法在顶层调用 React Hook“useState”。 React Hooks must be called in a React function component or a custom React Hook function. React Hooks 必须在 React function 组件或自定义 React Hook function 中调用。

or I've tried export const globalContext = React.createContext() , and got error Expected 1 arguments, but got 0.或者我试过export const globalContext = React.createContext() ,并得到错误Expected 1 arguments, but got 0.

So my question is how I can update the context's value in ts, could someone please help me?所以我的问题是如何在 ts 中更新上下文的值,有人可以帮助我吗?

You likely are wanting to provide a non-null default Context value.您可能希望提供一个非空的默认 Context 值。 The useState hook also returns an array, not an object with a login boolean property. useState挂钩还返回一个数组,而不是具有login boolean 属性的 object。 You want to pass an object with login as a property.您想要将 object 作为属性传递给login

const initContext: GlobalContext = {
  login: false,
}

export const globalContext = React.createContext(initContext); // <-- pass initContext as default value

function App() {
  const [login, setLogin] = useState<boolean>(false);

  return (
    <globalContext.Provider value={{ login }}>
      {useRoutes(router)}
    </globalContext.Provider>
  );
}

Update更新

If you need to update the login value then the setLogin state updater should be passed in the Context value as well.如果您需要更新login值,那么setLogin state updater 也应该在 Context 值中传递。

Example:例子:

interface IGlobalContext {
  login: boolean;
  setLogin: React.Dispatch<React.SetStateAction<boolean>>;
}

const initContext: IGlobalContext = {
  login: false,
  setLogin: () => {}
};

const GlobalContext = React.createContext(initContext);

const useGlobalContext = () => React.useContext(GlobalContext);

function App() {
  const [login, setLogin] = useState<boolean>(false);

  return (
    <GlobalContext.Provider value={{ login, setLogin }}>
      {useRoutes(router)}
    </GlobalContext.Provider>
  );
}

编辑 how-to-use-react-hooks-useeffect-usereducer-usecontext-to-change-contexts-val

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM