开发者问题收集

React Hook useState 返回未定义

2022-05-23
7024

我正尝试使用来自 API 的数据填充表格。

已更新*************

import React, { useMemo, useState, useCallback, useEffect } from "react";

import {
  AppLayout,
  Button,
  Box,
  Form,
  SpaceBetween,
  Grid,
} from "@affn/awsui-components-react/polaris";
import "@affn/awsui-global-styles/polaris.css";
import "./styles/landing-page.scss";
import { appLayoutLabels, externalLinkProps } from "./common/labels";
import Picture1 from "./resources/engineLogos/bric_team_dark_backgroung(1).svg";
import {
  ExternalLinkItem,
  Navigation,
  InfoLink,
} from "./commons/common-components-BRIC";

function BricPage() {
  
  const Content = ({ navigationOpen }) => {
    //Constants needed by the form ------------------------------------------------
    
    const refreshPage = () => {
      window.location.reload();
    };

    // The comment (i.e conversation) id must be unique
    const conversationId = uuidv4();

    //Function to handle submit click and create SIM
    const handleClick = (
      title1,
      description1,
    ) => () => {
      console.log(title1);
      console.log(description1);

    };

    const [GetSimIDs, setGetSimIDs] = React.useState([]); //Which is the impacted region?

  // Using useEffect to call the API once mounted and set the data
  useEffect(() => {
    window.harxny.api
      .invokeProxy(
        "/sit/ises?sort=createDate desc&q=status:(Open) containingFolder:(45-b5b9-4829-8b87-489053f9bb42)",
        {
          method: "GET",
          // SIM integration is only possible from the 'beta' and 'corp' stages.
          stage: "corp",
          headers: {
            "Content-Type": "application/json",
          },
        }
      ) //api finishes here
      .then((xhr) => {
        //response is captured here
        //var SIMID = JSON.parse(xhr.response).id;
        console.log(xhr.responseText);
        const data = JSON.parse(xhr.response);
        //const data = xhr.response;
        console.log(data);
        console.log(data.totalNumberFound);
        setGetSimIDs(data);
        console.log(GetSimIDs);
      });
  }, []);


    //End of Constants -------------------------------------------------------------
    console.log(GetSimIDs);
    return (
      <Box margin={{ bottom: "l" }}>
      
        <div className="center-form">
          <Box>
            <Grid
              gridDefinition={[
                {
                  colspan: { xl: "2", l: "2", s: "5", xxs: "10" },
                  offset: { l: "2", xxs: "1" },
                },
                {
                  colspan: { xl: "2", l: "3", s: "5", xxs: "10" },
                  offset: { s: "0", xxs: "1" },
                },
              ]}
            >
              <div className="custom-home-main-content-area">
                <SpaceBetween size="l">
                  <Form
                    actions={
                      <SpaceBetween direction="horizontal" size="xs">
                        <Button onClick={refreshPage} variant="link">
                          Reset Form
                        </Button>

                        <Button
                          variant="primary"
                          onClick={handleClick(
                            title1,
                            description1,
                          )}
                          ariaLabel="Submit"
                        >
                          Submit
                        </Button>
                      </SpaceBetween>
                    }
                  >
                  </Form>
                </SpaceBetween>
              </div>

            {/* Table goes here */}

            {console.log(GetSimIDs)}


              <tbody>
                <tr>
                  <th>title</th>
                  <th>Id</th>
                </tr>
                {GetSimIDs.documents.map((item, i) => (
                  <tr key={i}>
                    <td>{item.title}</td>
                    <td>{item.id}</td>
                  </tr>
                ))}
              </tbody>
            </Grid>
          </Box>
        </div>
      </Box>
    );
  };

  const [navigationOpen, setNavigationOpen] = React.useState(false);

  return (
    <AppLayout
      disableContentPaddings={true}
      content={<Content />}
      navigation={<Navigation activeHref="#/" />}
      navigationOpen={navigationOpen}
      onNavigationChange={({ detail }) => setNavigationOpen(detail.open)}
      toolsHide={true}
      ariaLabels={appLayoutLabels}
    />
  );
}

export default BricPage;

状态 GetSimIDs 已成功更新,数据如下:

{
  "documents": [
    {
      "assignedFolder": "4a37-416c-8531-",
      "extensions": {
        "tt": {
          "impact": 5,
          "category": "EiC",
          "type": "IBug",
          "item": "Macro",
          "assignedGroup": "EiC",
          "justification": [],
          "minImpact": 5,
          "status": "Assd"
        }
      },
      "watchers": [
        { "id": "[email protected]", "type": "email" },
        { "id": "[email protected]", "type": "email" },
        { "id": "[email protected]", "type": "email" },
        { "id": "[email protected]", "type": "email" }
      ],
      "customFields": {
        "number": [{ "id": "fte_saving", "value": 0 }],
        "date": [
          { "id": "delivery_date", "value": "2022-05-17T15:43:49.825Z" }
        ],
        "string": [
          { "id": "category_of_the_request", "value": "Other" },
          { "id": "region_of_impact", "value": "NA" },
          { "id": "tool_type", "value": "Excel Macro" },
          {
            "id": "impacted_tool",
            "value": "Tickets Helper"
          }
        ]
      }
     
    },
    {
      "title": "Issue or Bug - Global Wizard - NA",
      "assignedFolder": "416c-8531-37fa3a701712",
      
      "watchers": [{ "id": "[email protected]", "type": "email" }],
      "customFields": {
        "number": [{ "id": "fte_saving", "value": 0 }],
        "date": [
          { "id": "delivery_date", "value": "2022-05-13T02:22:46.751Z" }
        ],
        "string": [
          { "id": "category_of_the_request", "value": "Other" },
          { "id": "region_of_impact", "value": "NA" },
          { "id": "tool_type", "value": "Excel Macro" },
          { "id": "impacted_tool", "value": "Global Wizard" }
        ]
      }
      
    }
  ],
  "totalNumberFound": 2,
  "searchLogMessages": [],
  "startToken": ""
}

因此,我尝试使用以下代码更新表格:

<tbody>
                <tr>
                  <th>title</th>
                  <th>Id</th>
                  <th>status</th>
                </tr>
                {GetSimIDs.map((documents, i) => (
                  <tr key={i}>
                    <td>{documents.title}</td>
                    <td>{documents.id}</td>
                    <td>{documents.status}</td>
                  </tr>
                ))}
              </tbody>

但我一直收到一行错误

{GetSimIDs.map((documents, i) => ( 

提示 TypeError: s 未定义

您知道为什么似乎无法从钩子中获取数据吗?

我刚刚做出反应,因此非常感谢您的反馈。

谢谢 Luis V.

3个回答

这是异步数据的常见问题。状态最初未定义,并在请求完成后填充。在加载数据之前 始终 至少会进行一次渲染。

您可以通过多种方式解决此问题,但最简单的方法是将状态初始化为空数组:

const [GetSimIDs, setGetSimIDs] = React.useState([]);

现在状态始终已定义,您甚至可以在加载数据之前对其进行映射。

另一种选择是在映射数据之前检查数据:

{GetSimIDs && GetSimIDs.map((documents, i) => (
Brian Thompson
2022-05-23

从 API 返回的数据似乎是一个 object ,其属性为 documents ,而 documents 是一个 array 。您可以

setGetSimIDs(data.documents)

GetSimIDs.documents.map(...)

更新 ( Codesandbox ):似乎您还缺少一些空检查,因此出现错误。最初,对象 + 数组为空,因此我们无法使用 map 函数。只有当数据 成功 加载后,我们才能呈现行。

我已经使用了您的数据集 &制作了一个 模拟 api

export default function App() {
  const [GetSimIDs, setGetSimIDs] = useState({});

  useEffect(() => {
    axios
      .get("https://getsimids.free.beeceptor.com/my/api/path")
      .then((res) => {
        setGetSimIDs(res.data);
      });
  }, []);
  return (
    <div className="App">
      <table>
        <tbody>
          <tr>
            <th>title</th>
            <th>Id</th>
            <th>status</th>
          </tr>
          {GetSimIDs.documents &&
            GetSimIDs.documents.length > 0 &&
            GetSimIDs.documents.map((documents, i) => (
              <tr key={i}>
                <td>{documents.title}</td>
                <td>{documents.id}</td>
                <td>{documents.status}</td>
              </tr>
            ))}
        </tbody>
      </table>
    </div>
  );
}
A G
2022-05-23

首先,您可以在 map 函数之前记录 GetSimIDs 和 GetSimIDs 的值。

console.log(GetSimIDs, GetSimIDs.documents)
GetSimIDs.map...

它可能是 undefined ,因为在第一次加载页面时它尚未初始化。

我建议您设置 const [GetSimIDs, setGetSimIDs] = React.useState([]); 而不是空。

对于您使用 react hooks (useEffect) 的进一步问题,我建议您在 useEffect 之外使用 setState 。提取获取数据的方法,例如 getData ,然后在 useEffect() 内使用它。

useEffect(()=>{getData()},[])
besjon_c
2022-05-23