React钩子JSX渲染无法正常工作

时间:2020-11-03 18:55:25

标签: reactjs react-hooks jsx

我有5个从API返回的持卡人,我需要渲染所有5个持卡人,但它仅渲染第一个持卡人。当我记录持卡人时,它将记录5个持卡人的阵列。但是,在我映射它们并在我的renderCardHolders中返回JSX之后,它仅呈现第一个返回的用户。有人可以帮我吗?

function UserContainer (props) {
    const [cardHolders, setCardHolders] = useState([{}])

        useEffect(() => {
        props.fetchedData.map(user => {
            try {
                const uuid = user.Guid
                const response = Api.get(`/securityCenterApi/getCredentials/${uuid}`)
                .then(response => {
                    const cardHolderCredentials = response.data.Rsp.Result.Credentials    
                    const newGuid = Api.get(`/securityCenterApi/getUsers/${cardHolderCredentials}`)
                    .then(response => {
                        
                        const userName = response.data.Rsp.Result.Cardholder.Name
                        const bitLength = response.data.Rsp.Result.Format.BitLength
                        const facilityCode = response.data.Rsp.Result.Format.Facility
                        const cardNumber = response.data.Rsp.Result.Format.CardId
                        
                        setCardHolders([{
                            username: userName,
                            bitLength: bitLength,
                            facilityCode: facilityCode,
                            cardNumber: cardNumber
                        }])
                    }
                    )
                })
            } catch (err) {
                console.log(err)
            }
        
        })
}, [props.fetchedData])

    // console.log(cardHolders)
    const renderCardHolders = () => {
        return cardHolders.map((cardHolder, index) => {
                console.log(cardHolder)
            return (
                <tr key={index}>
                    <th>{cardHolder.username}</th>
                    <td>{cardHolder.bitLength}</td>
                    <td>{cardHolder.facilityCode}</td>
                    <td>{cardHolder.cardNumber}</td>
                </tr>
            )
        })
    }

    return (
    <table className="table">
        <thead>
            <tr>
            <th><abbr title="Position">Cardholder name</abbr></th>
            <th>Wiegand Bit type</th>
            <th><abbr title="Played">Facility Code</abbr></th>
            <th><abbr title="Won">Card number</abbr></th>
            </tr>
        </thead>
        <tbody>
            {renderCardHolders()}
        </tbody>
    </table>
    )
}

export default UserContainer

谢谢!

1 个答案:

答案 0 :(得分:1)

我模拟了API调用,一切似乎都正常了。但是,虽然根据您的代码对其进行模拟,但看起来第一个API调用仅返回一个用户。您的意思是将状态设置为对象数组吗?像这样:

setCardHolders(prev => [...prev, {
  username: userName,
  bitLength: bitLength,
  facilityCode: facilityCode,
  cardNumber: cardNumber
}])

此外,您可能想使用空数组初始化状态:

const [cardHolders, setCardHolders] = useState([]);

这里是working example

import React, { useEffect, useState } from "react";
import "./styles.css";

function UserContainer(props) {
  const [cardHolders, setCardHolders] = useState([]);

  useEffect(() => {
    props.fetchedData.forEach((user) => {
      try {
        const uuid = user.Guid;
        console.log("uuid", uuid);
        Promise.resolve({
          data: { Rsp: { Result: { Credentials: "testcreds" } } }
        }).then((response) => {
          const cardHolderCredentials = response.data.Rsp.Result.Credentials;
          console.log(cardHolderCredentials); // Verify
          Promise.resolve({
            data: {
              Rsp: {
                Result: {
                  Cardholder: { Name: "Test Name" },
                  Format: {
                    BitLength: 1,
                    CardId: "CardId1",
                    Facility: "My Facility"
                  }
                }
              }
            }
          }).then((response) => {
            const userName = response.data.Rsp.Result.Cardholder.Name;
            const bitLength = response.data.Rsp.Result.Format.BitLength;
            const facilityCode = response.data.Rsp.Result.Format.Facility;
            const cardNumber = response.data.Rsp.Result.Format.CardId;

            setCardHolders((prev) => [
              ...prev,
              {
                username: userName,
                bitLength: bitLength,
                facilityCode: facilityCode,
                cardNumber: cardNumber
              }
            ]);
          });
        });
      } catch (err) {
        console.log(err);
      }
    });
  }, [props.fetchedData]);

  // console.log(cardHolders)
  const renderCardHolders = () => {
    return cardHolders.map((cardHolder, index) => {
      console.log(cardHolder);
      return (
        <tr key={index}>
          <th>{cardHolder.username}</th>
          <td>{cardHolder.bitLength}</td>
          <td>{cardHolder.facilityCode}</td>
          <td>{cardHolder.cardNumber}</td>
        </tr>
      );
    });
  };

  return (
    <table className="table">
      <thead>
        <tr>
          <th>
            <abbr title="Position">Cardholder name</abbr>
          </th>
          <th>Wiegand Bit type</th>
          <th>
            <abbr title="Played">Facility Code</abbr>
          </th>
          <th>
            <abbr title="Won">Card number</abbr>
          </th>
        </tr>
      </thead>
      <tbody>{renderCardHolders()}</tbody>
    </table>
  );
}

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <UserContainer fetchedData={[{ Guid: "1" }, { Guid: "2" }]} />
    </div>
  );
}