React Hook useState 返回未定义

React Hook useState Is Returning Undefined

我正在尝试用来自 API 的数据填充 table。

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

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": "bric-primary@amazon.com", "type": "email" },
        { "id": "sssesuni@amazon.com", "type": "email" },
        { "id": "raaishwa@amazon.com", "type": "email" },
        { "id": "dipchakr@amazon.com", "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": "bprimary@a.com", "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": ""
}

所以我尝试使用以下代码更新 table:

<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 is undefined

知道为什么它似乎没有从挂钩中获取数据吗?

我对反应还很陌生,所以欢迎所有反馈。

谢谢 路易斯诉

从 API 返回的数据似乎是 object,属性 documentsarray。你可以

setGetSimIDs(data.documents)

GetSimIDs.documents.map(...)

Update (Codesandbox):似乎您还缺少一些空检查,因此存在错误。最初对象+数组是空的,所以我们不能使用 map 函数。只有当数据 成功 加载后,我们才能呈现行。

我已经使用了您的数据集并制作了 mock 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>
  );
}

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

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

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

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

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

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

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

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

它可能会 undefined 因为在第一次加载页面时它没有被初始化。

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

对于反应挂钩 (useEffect) 的进一步问题,我建议您 setStateuseEffect 之外。提取获取数据的方法,例如 getData,然后在 useEffect()

中使用它
useEffect(()=>{getData()},[])