如何在useEffect渲染之前填充对象

时间:2020-10-16 19:12:54

标签: javascript reactjs typescript react-hooks

当组件渲染时,我必须填充对象,然后显示该信息。 现在,我试图这样做,但是我想出错了,因为当我尝试渲染信息对象时仍然是空的。 我该如何解决这个问题?

console.log shows
{}
{}
{name: "Name"}
{name: "Name"}

export const UserCard: React.FC = () => {
let [mainInfo, setMainInfo] = useState({});

  useEffect(() => {
    setMainInfo({
      name: "Name"
    })
  }, [])

  console.log(mainInfo)
  return (
    <h1>{mainInfo.name}</h1>
 );
};

1 个答案:

答案 0 :(得分:0)

Typescript official docs

当您这样设置时:

let [mainInfo, setMainInfo] = useState({});

Typescript知道mainInfo的类型为{}。即:一个没有任何属性的空对象。

因此,当您尝试访问:mainInfo.name时,Typescript会告诉您name在空对象上不存在,空对象是为mainInfo隐式定义的类型。

我不知道您的用例,但是可能的解决方法如下:

interface MainInfo {
  name?: string;
}

const UserCard: React.FC = () => {
  let [mainInfo, setMainInfo] = useState<MainInfo>({});

  useEffect(() => {
    setTimeout(() => {
      setMainInfo({
        name: "Name"
      });
    }, 1000);
  }, []);

  return <h1>{mainInfo.name || "Loading..."}</h1>;
};

您需要为mainInfo状态定义类型。因此,在上面的示例中,我将其设置为具有可选属性name的对象,如下所示:

interface MainInfo {
  name?: string
}

通过执行以下操作,我明确地告诉Typescript mainInfo属于该类型:

let [mainInfo, setMainInfo] = useState<MainInfo>({});

CodeSandbox Link

现在,所有错误都消失了。

enter image description here

PS:我添加了setTimeout以模拟一些异步数据。因为我看不到其他原因,所以您不会这样做:useState({name: "NAME"});而不是将其设置在useEffect内。