首页 > 解决方案 > 你如何处理加载时 Typescript 类型的局部状态变量?

问题描述

我最近开始研究一个使用 Typescript 的 React 项目,我遇到了一个特殊的问题,我无法弄清楚它在 typescript 中是如何处理的。React 项目很常见,我确信有办法处理它,但还没有找到有用的文档。

import * as React from "react"; 
import { useDispatch, useSelector } from "react-redux-consumer";
import { loadFoo } from "reduxActions/action";

type FooType = {
  hello: HelloWorldType; 
  world: HelloWorldType;
}

type HelloWorldType = {
  name: string;
  value: string;
}

const MyComponent = () => {
  // On load foo value hasn't been loaded yet. Initialize it to empty
  const [currentFoo, setCurrentFoo] = React.useState<HelloWorldType>(); 
  const foo = useSelector(state => state.foo);
  const dispatch = useDispatch();

  React.useEffect(() => {
    dispatch(loadFoo());
  }, [loadFoo]);

  return (
    <div>
      <InputComponent currentFoo={currentFoo} setCurrentFoo={setCurrentFoo}/>
    </div>
  ); 
}

export type setCurrentFoo = React.Dispatch<
  React.SetStateAction<HelloWorldType>
>;

type InputComponentPropType = {
 currentFoo: HelloWorldType;
 setCurrentFoo: setCurrentFoo;
}

const InputComponent = (props: InputComponentPropType) => {
   const {currentFoo, setCurrentFoo} = props;
    return (
         <input 
            type="checkbox" 
            id="hello" 
            name={currentFoo.name} 
            value={currentFoo.value} 
            onChange={e => {
              setCurrentFoo(currentFoo)
            }
         />
    );
}

在上面的代码示例中,我的currentFoo变量需要是类型HelloWorld,但我的问题是我实际上没有值,直到我从我的 redux 状态加载它或从 api 获取它。在这种情况下,我会收到 Typescript 错误,MyComponent并且InputComponent该类型HelloWorldundefined.

你如何初始化currentFood状态变量,将它变成一个你必须在任何地方都支持类型的组件链undefined?这可能吗

标签: reactjstypescriptreact-redux

解决方案


MyComponent中,您可以定义currentFooHelloWorldTypeorundefined并且在InputComponentPropType您可以将currentFoo属性标记为可选,并在设置输入字段的nameor时进行检查。value如果currentFoo不存在,则将其分配给某个默认值。我已将其分配给下面的空字符串,但您可以为其分配任何值。

import * as React from "react"; 
import { useDispatch, useSelector } from "react-redux-consumer";
import { loadFoo } from "reduxActions/action";

type FooType = {
  hello: HelloWorldType; 
  world: HelloWorldType;
}

type HelloWorldType = {
  name: string;
  value: string;
}

const MyComponent = () => {
  // On load foo value hasn't been loaded yet. Initialize it to empty
  const [currentFoo, setCurrentFoo] = React.useState<HelloWorldType|undefined>(); 
  const foo = useSelector(state => state.foo);
  const dispatch = useDispatch();

  React.useEffect(() => {
    dispatch(loadFoo());
  }, [loadFoo]);

  return (
    <div>
      <InputComponent currentFoo={currentFoo} setCurrentFoo={setCurrentFoo}/>
    </div>
  ); 
}

export type setCurrentFoo = React.Dispatch<
  React.SetStateAction<HelloWorldType>
>;

type InputComponentPropType = {
 currentFoo?: HelloWorldType; // '?' makes this property/field optional
 setCurrentFoo: setCurrentFoo;
}

const InputComponent = (props: InputComponentPropType) => {
   const {currentFoo, setCurrentFoo} = props;
    return (
         <input 
            type="checkbox" 
            id="hello" 
            name={currentFoo?.name || ""} 
            value={currentFoo?.value || ""} 
            onChange={e => {
              setCurrentFoo(currentFoo)
            }
         />
    );
}

或者

一个更简单的方法是用一个虚拟值初始化currentFoo内部MyComponent

  const [currentFoo, setCurrentFoo] = React.useState<HelloWorldType>({ name: "", value: "" });

推荐阅读