使用 React Hooks,使用 "useState" 和 "useEffect",有没有办法渲染状态等待状态有值?

Using React Hooks, using "useState" and "useEffect", is there a way to render a state waiting till the state has a value?

我想做什么?

通过 React Hooks 将 characterInfo 渲染到前端。

目前尝试执行此操作的代码是什么?

渲染信息的前端组件:

export default function ReactComponent() {
  const [characterInfo, setCharacterInfo] = useState([]);

  useEffect(() => {
    socket.emit("/character/read");
    socket.on("/character/read", function (data) {
      if (data.status === "SUCCESS") {
        setCharacterInfo(data)
      }
    });
    return () => {
      socket.off("/character/read");
    };
  }, []);

  return (
    <div>
      {characterInfo.models[0].name}
    </div>
  )
}

作为“数据”的后端 .json 信息以及 setCharacterInfo 保存到 characterInfo 的内容:

{
  status: "SUCCESS"
  models: [
    { 
      name: "AC",
      element: "Air",
    }
    {
      name: "Irene",
      element: "Fire",
    }
  ]
}

(所以在这种情况下访问“AC”,它将是 characterInfo.models[0].name

我期望结果是什么?

我希望只呈现 AC

实际结果如何?

我会得到这个错误:

TypeError: Cannot read property '0' of undefined

我认为可能是什么问题?

我认为它必须处理异步平衡,尤其是useEffect()。我认为前端会在 setCharacterInfo 甚至决定设置任何内容之前尝试渲染。

您可以调整您的 return 语句以仅呈现名称 if/when 它存在

return (
    <div>
      {characterInfo.length && characterInfo.models[0].name}
    </div>
  )

I think the front-end tries to render before setCharacterInfo decides to even set anything.

没错,在 useEffect 中的函数为 运行 之前,您的组件使用默认 useState 值渲染一次。这是组件安装、更新和卸载时的执行顺序图(注意 render 发生在 useEffect 之前):

https://raw.githubusercontent.com/donavon/hook-flow/master/hook-flow.png

在访问 name.

之前,您需要检查 characterInfo.models 是否存在(为了安全起见,请确保它有长度)
  return (
    <div>
      {
        characterInfo.models &&
        characterInfo.models.length &&
        characterInfo.models[0].name
      }
    </div>
  )

或者,如果您使用的是可选链接:

  return (
    <div>
      {characterInfo?.models[0]?.name}
    </div>
  )

另一个注意事项 - 您将 characterInfo 的初始值设置为一个空数组。如果你把它变成一个空对象,那么你期望 data 是一个对象而不是数组会更清楚。

const [characterInfo, setCharacterInfo] = useState({});