• React 与 TS 结合使用 Hook 总结


    在学习 React 时,我们总会遇到在 TS 和 JS 之间切换来开发多个项目,而有时会忘记 TS 的语法,所以编写一下 React 结合 TS 开发时的一些总结知识点,以便后续回顾用。

    **说明:**这只是总结 React 与 TS 结合使用时的写法回顾,并不是介绍钩子函数的使用。

    使用 userState

    这节主要是回顾 useState 钩子函数的 TS 的写法。实例如下:

    type AuthUserProp = {
      name: string;
      email: string;
    };
    
    const UseStartProps: React.FC = () => {
      const [authUser, setAuthUser] = useState<AuthUserProp | null>(null);
      const [isLogin, setIsLogin] = useState<boolean>(false);
    
      return (
        <div>
          <h2>useStart 使用实例</h2>
          <button
            onClick={() => {
              setIsLogin(true);
              setAuthUser({ name: "Tom", email: "tom@example.com" });
            }}
          >
            登录
          </button>
          <button
            onClick={() => {
              setIsLogin(false);
              setAuthUser(null);
            }}
          >
            登出
          </button>
          {isLogin ? (
            <div>
              <p>{authUser?.name}</p>
              <p>{authUser?.email}</p>
            </div>
          ) : (
            <div>还未登录</div>
          )}
        </div>
      );
    };
    
    export default UseStartProps;
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    使用 useReducer

    这节主要是回顾 useReducer 钩子函数的 TS 写法,以及 TS 联合类型 使用方式。实例如下:

    type CounterState = {
      count: number;
    };
    
    type UpdateAction = {
      type: "increment" | "decrement";
      payload: number;
    };
    
    type ResetAction = {
      type: "reset";
    };
    
    type CounterAction = UpdateAction | ResetAction; // 因为重置操作并不需要type这个参数,所以通过TS的类型推导来做判断
    
    const UseReducerProps: React.FC = () => {
      const initialState = { count: 0 };
    
      function reducer(state: CounterState, action: CounterAction) {
        switch (action.type) {
          case "increment":
            return { count: state.count + action.payload };
          case "decrement":
            return { count: state.count - action.payload };
          case "reset":
            return initialState;
          default:
            return state;
        }
      }
    
      const [state, dispatch] = useReducer(reducer, initialState);
    
      return (
        <div>
          <h2>useReducer 使用实例</h2>
          Count: {state.count}
          <button onClick={() => dispatch({ type: "increment", payload: 10 })}>
            添加 10
          </button>
          <button onClick={() => dispatch({ type: "decrement", payload: 10 })}>
            减去 10
          </button>
          <button onClick={() => dispatch({ type: "reset" })}>重置</button>
        </div>
      );
    };
    
    export default UseReducerProps;
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    使用 useContext

    这节主要是回顾 useContext 钩子函数的 TS 写法,以及 useContext 于 useStart 钩子函数使用时的写法。实例如下:

    • userContext 钩子函数使用
    // ThemeContext.tsx
    type ThemeContextProviderProps = {
      children: React.ReactNode;
    };
    
    export const ThemeContext = createContext(theme);
    
    export const ThemeContextProvider = ({
      children,
    }: ThemeContextProviderProps) => {
      return (
        <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
      );
    };
    
    // Box.tsx
    const Box: React.FC = () => {
      const theme = useContext(ThemeContext);
    
      return (
        <div
          style={{
            backgroundColor: theme.secondary.main,
            color: theme.secondary.text,
          }}
        >
          Theme context
        </div>
      );
    };
    
    export default Box;
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • useContext 和 useStart 钩子函数使用
    // UserContext.tsx
    type AuthUser = {
      name: string;
      email: string;
    };
    
    type UserContextType = {
      user: AuthUser | null;
      setUser: React.Dispatch<React.SetStateAction<AuthUser | null>>;
    };
    
    type UserContextProviderProps = {
      children: React.ReactNode;
    };
    
    // 这里可以写成 export const UserContext = createContext({} as UserContextType),但是不建议这这样,这样做不好判断context的值是否为空
    export const UserContext = createContext<UserContextType | null>(null);
    
    export const UserContextProvider = ({ children }: UserContextProviderProps) => {
      const [user, setUser] = useState<AuthUser | null>(null);
    
      return (
        <UserContext.Provider value={{ user: user, setUser: setUser }}>
          {children}
        </UserContext.Provider>
      );
    };
    
    // User.tsx
    export const User = () => {
      const userContext = useContext(UserContext);
    
      const handleLogin = () => {
        userContext?.setUser({
          name: "Vishwas",
          email: "asd@asd.com",
        });
      };
    
      const handleLogout = () => {
        userContext?.setUser(null);
      };
      return (
        <div>
          <button onClick={handleLogin}>Login</button>
          <button onClick={handleLogout}>Logout</button>
          <div>用户名: {userContext?.user?.name}</div>
          <div>用户邮箱: {userContext?.user?.email}</div>
        </div>
      );
    };
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    使用 useRef

    这节主要是回顾 useRef 钩子函数的 TS 写法。实例如下:

    • DOM 元素
    export const DomRef = () => {
      const inputRef = useRef<HTMLInputElement>(null!);
      useEffect(() => {
        inputRef.current.focus();
      }, []);
      return (
        <div>
          <input type="text" ref={inputRef} />
        </div>
      );
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 可变 ref(setTimeout 为例)
    export const MutableRef = () => {
      const [timer, setTimer] = useState(0);
      const interValRef = useRef<number | null>(null);
    
      const stopTimer = () => {
        if (interValRef.current) {
          window.clearInterval(interValRef.current);
        }
      };
      useEffect(() => {
        interValRef.current = window.setInterval(() => {
          setTimer((timer) => timer + 1);
        }, 1000);
        return () => {
          stopTimer();
        };
      }, []);
    
      return (
        <div>
          HookTimer - {timer} -
          <button onClick={() => stopTimer()}>Stop Timer</button>
        </div>
      );
    };
    
    • 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
  • 相关阅读:
    Centos8下载安装JDK8
    JavaWeb核心(2)
    18亿欧元大动作,法国瞄准实现量子飞跃
    复习一下Linux常用命令,孰能生巧~
    【机器学习Python实战】logistic回归
    Java配置39-搭建ELK服务器
    c#中原型模式详解
    微服务实战|集中配置中心Config对称加密实战
    杰理之CMD_SET_BLE_VISIBILITY【篇】
    解决docker通过volumes挂载文件,宿主机修改后容器内不同步,重启服务才能同步
  • 原文地址:https://blog.csdn.net/qq_33003143/article/details/132778162