在React中创建自定义的钩子状态并从任何地方操纵全局状态,而无需使用任何第三方状态管理库

时间:2020-08-07 12:02:08

标签: javascript reactjs typescript react-hooks

您可以获取,请在此StackBlitz Link

中引用

我在项目的todoState.ts文件夹中有一个文件夹文件modelstodoState.ts用于使用自定义钩子管理应用程序的全局状态。我需要在全局todoState.ts上执行以下任务。.

  1. 添加新州
  2. 删除状态
  3. 更新状态

这是todoState.ts的代码。

import { useState, useEffect } from "react";

const todoState = (todo?, callback?) => {
      const [todos, setTodos] = useState([todo]);

      useEffect(()=>{
          setTodos(todo);
      },[])

    return [{todos, setTodos}];
}

现在,我有两个用户定义的组件,它们依赖于globalState。分别是1. <TodoForm /><TodoListLineItem />

两者都在index.tsx内部呈现。

如何从包括index.tsx<TodoForm /><TodoListLineItem />的所有组件中管理全局状态。 在这里 ...

  1. <TodoForm />,用于添加到要列出的任务。
  2. <TodoListLineItem />,用于显示TodoForm组件中所有添加的任务。当用户将鼠标悬停在每个待办事项列表项上时,用户便可以从全局管理状态中删除特定的任务项。

哪种是实现此全局管理状态功能的最佳且可重用的方法?

仅通过操纵应用程序的全局状态对象,如何将一个组件从A更改为B的状态如何反映在相关组件上。如果我将useState([])放入index.tsx,那么它将很好用,但是我想从TodoState.ts文件管理状态。谢谢。

导出默认的todoState;

1 个答案:

答案 0 :(得分:0)

最后,我发现并学习了React-Context API的新概念。您可以在这里StackBlitz Link

结帐

为了管理全局状态,React提供了context-api。仅当您具有多个级别的组件属性时,才使用该组件树在组件树中从上到下传递。我使用了一个非常小的示例来了解针对不同用例的上下文api。

首先,我们需要使用两个上下文。

  1. createContext [用于创建全局状态上下文]
  2. useContext [用于从子组件的上下文中获取状态]。

要与上下文一起使用,我创建了一个<context.Provider>组件。并且所有状态管理任务仅在此组件级别完成。所有子组件都只是发送事件信息。提供商组件的全局上下文也会相应更改。

首先,创建上下文。

export interface ItodoContext{
  todoState? : Itodo[];
  addNewTodoState?: (state?: string) => void;
  removeTodoItemByIndex? : (index?: number) => void;
}

export const todoContext = createContext<ItodoContext[]>([{}]);

我正在使用React-Typescript功能组件,根据上下文接口定义了状态的所有任务。我传递了所有TodoState函数,以便像addNewTodoState,removeTodoItemByIndex这样操作TodoState。

然后创建上下文的提供程序。

const allTodoStates = {
  todoState,
  addNewTodoState,
  removeTodoItemByIndex
}

return(
  <todoContext.Provider value = { [allTodoStates]}>      
     {props.children}
  </todoContext.Provider>
)

然后我将Provider设置为index.tsx组件中树的父组件。

 const App: FC = () => {
 return (
   <div className="h-100 w-100">
     <TodoStateProvider>
       <Navbar />
       <div className="container">
         <TodoForm />  
         <TodoListLineItem />
       </div>
     </TodoStateProvider>
   </div>
 );  
}

首先请参阅所有<TodoStateProvider>父组件的子组件。

我需要在<TodoForm>内向上下文添加新状态时,如何添加状态如下代码所示。

const [{addNewTodoState}] = useContext(todoContext);

const sendTodoItem = (e) => {
      addNewTodoState(todoInput.trim());
}

等。.提供程序组件具有value属性,我们可以使用useContext()挂钩从子级获取这些属性。正如我们上面所使用的。请参阅上面StackBlitz链接中随附的完整工作演示。