【问题标题】:How can I fill object before render by useEffect如何在使用 useEffect 渲染之前填充对象
【发布时间】:2020-10-16 19:12:54
【问题描述】:

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

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>
 );
};

【问题讨论】:

  • 应该可以。你能分享你的整个代码还是把它放在沙箱里?
  • 不确定您的确切用例,但如果您只想预设mainInfo,您可以删除整个useEffect 并将{name: "Name"} 移动到useState({name: "Name"});。如果您的意思是错误是因为您还没有数据,那么您需要在渲染之前添加一个条件,例如if(mainInfo.name)。见React Conditional Rendering
  • 对不起,我没有说我使用打字稿可能因为它不起作用
  • 也许:&lt;h1&gt;{mainInfo.name || '' }&lt;/h1&gt;
  • 不,不起作用(

标签: javascript reactjs typescript react-hooks


【解决方案1】:

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

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

PS:我添加了一个setTimeout 来模拟一些异步数据。因为我看不出您为什么不这样做的任何其他原因:useState({name: "NAME"}); 而不是将其设置在 useEffect 中。

【讨论】:

    猜你喜欢
    • 2020-12-21
    • 1970-01-01
    • 2020-02-12
    • 2017-07-23
    • 1970-01-01
    • 2021-01-04
    • 2019-11-18
    • 2021-11-21
    • 2017-01-06
    相关资源
    最近更新 更多