【问题标题】:React hooks JSX rendering not working properlyReact hooks JSX 渲染无法正常工作
【发布时间】:2021-02-16 11:41:26
【问题描述】:

我有 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

提前致谢!

【问题讨论】:

    标签: reactjs react-hooks jsx


    【解决方案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>
      );
    }
    

    【讨论】:

    • 谢谢杰克!我在将 setState 设置为数组时遇到问题,您的回答解决了这个问题。赞赏!
    • 嘿,杰克,当我在处理上面的代码时,每次单击按钮时,它都会不断地将持卡人添加到先前呈现的持卡人中。前任。单击按钮后呈现的 5 个持卡人。当我再次单击该按钮时,将 5 个持卡人添加到之前的 5 个持卡人中,这样总共有 10 个持卡人。单击按钮时需要重新渲染
    • 我不确定您指的是哪个按钮,但听起来您正在将新的项目列表添加到现有列表中。我会检查你的 setState 调用并确保逻辑正确。
    • 按钮在父组件中,我以为我在子组件中有它。基本上,如果我单击父组件中的按钮,renderCardHolders 函数会再次执行,而不是重新加载页面,而是将获取的数据连接到先前的状态。相信我的 useEffect 钩子有问题或与 setCardHolders() 有什么关系
    猜你喜欢
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 2018-07-30
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多