使用 useEffect 和 useState 未定义的反应状态

问题描述 投票:0回答:4

跨多个组件获取相同的(状态)未定义错误。我已经检查并发现数据确实来自 API,没有被 CORS 或其他东西阻止,并且可用于 useEffect 回调。问题似乎在于设置状态。我尝试用 useRef 钩子替换 useState 钩子并在访问 ref.current 时得到相同的结果。

真正奇怪的是,几天前一切正常,所以我开始处理后端代码,今天却出现白屏。

错误,熟悉的:

Uncaught TypeError: can't access property "map", data is undefined

编辑:解决方案 - TypeError 是由于数据有效负载结构更改时的实际类型转换引起的。

Dashboard.tsx 索引路由。

export default function Dashboard() {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState<ServiceStatus[]>([]);

  useEffect(() => {
    setLoading(true);
    server.monitor.services()
      .then(data => setData(data))
      .finally(() => setLoading(false));
  }, []);

  return (
    <div>
      <Title order={2}>Dashboard</Title>
      <BackToTop />
      <div>
        <LoadingOverlay visible={loading} overlayBlur={2} />
        {data
          .map(svc => <ServiceStatusListItem key={svc.value?.ServiceName} status={svc} />)}
      </div>
    </div>
  );
}

server.ts

export const server = {
  monitor: {
    services: async () => {
      const url = `${hostname}/Monitor/Services`;
      const statuses = await fetch(url, addAuthorization()).then(resp => resp.json());
      return statuses as ServiceStatus[];
    }
  }
};

截图可在https://imgur.com/a/Rbgi8Ba.

reactjs typescript react-hooks react-dom
4个回答
0
投票

你必须等待 jsx 渲染直到加载完成,我假设数据数组的长度大于 0

export default function Dashboard() {
    const [loading, setLoading] = useState(true);
    const [data, setData] = useState<ServiceStatus[]>([]);
  
    useEffect(() => {
      setLoading(true);
      server.monitor.services()
        .then(data => setData(data))
        .finally(() => setLoading(false));
    }, []);
    if(loading) return <p>Loading...</p>
    return (
      <div>
        <Title order={2}>Dashboard</Title>
        <BackToTop />
        <div>
          <LoadingOverlay visible={loading} overlayBlur={2} />
          {data
            .map(svc => <ServiceStatusListItem key={svc.value?.ServiceName} status={svc} />)}
        </div>
      </div>
    );
  }

0
投票

我认为,

data
是包含价值=
undefined
所以你应该检查它的数据是否包含所谓的虚假值以外的一些值,例如 (NULL, undefined)

你可以这样做

{data?.map(svc => <ServiceStatusListItem key={svc.value?.ServiceName} status={svc} />)}

{if(data) {data.map(svc => <ServiceStatusListItem key={svc.value?.ServiceName} status={svc} />)}}

{data && data.map(svc => <ServiceStatusListItem key={svc.value?.ServiceName} status={svc} />)}

正如你提到的,useState 有问题 这是你应该尝试的东西

useEffect(() => {
    setLoading(true);
    server.monitor.services()
      .then((data) => {setData(data)})
      .finally(() => setLoading(false));
  }, []);

0
投票

我的猜测是你必须暂停执行,直到 Promise 得到解决,你这样做如下,

  useEffect(() => {
    setLoading(true);
    
    const fetchStatuses = async () => {
      const res = await server.monitor.services()
      .then(data => setData(data))
      .finally(() => setLoading(false));
      return res
    }

    fetchStatuses()
  }, []);

查看此链接,了解有关在 useEffect 挂钩中使用异步函数的更多详细信息。


0
投票

Konrad 和 Adam 是对的,对后端的更改确实导致访问和显示数据时出错。

今天我开始处理后端代码,但出现白屏 - 您的后端没有返回任何数据

修改 server.ts 解决了问题。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.