useContext局部状态管理

2023/3/24

# useContext定义局部状态

  • ./services/useTheme.jsx
import React, { useState, createContext, useContext } from "react";

const ThemeContext = createContext(null);
const DispatchContext = createContext(null);

const useTheme = () => useContext(ThemeContext);
const useThemeDispatch = () => useContext(DispatchContext);

const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState("dark");
  const changeTheme = (newV) => {
    setTheme(newV);
  };

  return (
    <ThemeContext.Provider value={theme}>
      <DispatchContext.Provider value={changeTheme}>
        {children}
      </DispatchContext.Provider>
    </ThemeContext.Provider>
  );
};

export { useTheme, useThemeDispatch };
export default ThemeProvider;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 局部使用状态

import React, { memo } from "react";
import ThemeProvider, { useTheme } from "./services/useTheme";

const Home = () => {
  const theme = useTheme();
  return
  <div style={{color: theme === "dark" ? "white" : "black"}}>
    111
  </div>
}

// 将Home组件包装,从Home往下都能够使用这个局部状态
// 或者直接从路由做这一层包装
const WrapperedThemeHome = () => {
  return (
    <ThemeProvider>
      <Home />
    </ThemeProvider>
  );
};
export default memo(WrapperedThemeHome);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 状态更改

  • Home下的子组件
import React, { memo } from "react";
import ThemeProvider, { useTheme } from "./services/useTheme";
const Menu = () => {
  const theme = useTheme();
  const themeDispatch = useThemeDispatch();
  const changeMenuItem = () => {
    themeDispatch(theme === "light" ? "dark" : "light");
  };
  return (
    <button onClick={changeMenuItem}>{theme}</button>
  );
};
export default memo(Menu);
1
2
3
4
5
6
7
8
9
10
11
12
13

# 性能调优

  • 某一个组件更新,其子组件都会更新,尤其是一个页面多个地方在使用这个状态的时候,需要用memo(Component)来减少局部无效更新

# useContext对比Redux

选择标准

redux context
范围 全局 局部
状态个数 三个以上 三个以下
项目大小 超大 中小

# Provider

上次更新: 11/1/2024