AwesomeDevin / blog

Welcome to Devin's blog,I'm trying to be a fullstack developer and sticking with it !!!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

【Javascript】抛弃Redux + flux**,使用 react hooks + context 进行方便快捷的全局状态管理

AwesomeDevin opened this issue · comments

该方案主要分为三步:1. 基于 hooks 构建 Store 2. 将 Store 基于 context 传递给子组件 3. 子组件更新 Store,并触发渲染,该方案不适用于复杂应用

1.构建Store

userStore.tsx

import { useState } from 'react'
export default function useUserStore () {
  const [user, setUser] = useState<IUser>({  })

  return {
    setUser,
    user,
  }
}

loginStore.tsx

import { useState } from 'react'
export default function useLoginStore () {
  const [login, setLogin] = useState(false)

  return {
    login,
    setLogin,
  }
}

2.将 Store 基于 context 传递给子组件

context.tsx

import useUserStore from "./userStore";
import useLoginStore from "./loginStore";
import { createContext } from "react";

export const context = createContext(null);
export default function Context({ children }) {
  const userStore = useUserStore();
  const loginStore = useLoginStore();

  console.log("userStore", userStore);

  const contextValue = {
    userStore,
    loginStore
  };

  return <context.Provider value={contextValue}>{children}</context.Provider>;
}

app.tsx

import Context from "./context";
import Child from "./child";

export default function Index() {
  return (
    <Context>
      <Child />
    </Context>
  );
}

3.子组件更新 Store,并触发渲染,该方案不适用于复杂应用

child.tsx

import { useContext, useEffect } from "react";
import { context } from "./context";

export default function Child() {
  const store = useContext(context);
  console.log(store);
  const { user, setUser } = store?.userStore || {};
  const { login, setLogin } = store?.loginStore || {};

  useEffect(() => {
    setTimeout(() => {
      setUser({ name: "AwesomeDevin" });
      setLogin(true);
    }, 2000);
  }, [setUser, setLogin]);

  return (
    <div>
      <p>{user?.name || "未命名"}</p>
      <p>{login ? "已登陆" : "未登录"}</p>
    </div>
  );
}

在线DEMO https://codesandbox.io/s/react-context-ease-store-lv1ibp?file=/src/App.js