【问题标题】:How do I pull data from object in array as state is being updated in React with hooks?当 React 中使用钩子更新状态时,如何从数组中的对象中提取数据?
【发布时间】:2020-04-09 23:58:50
【问题描述】:

这是上一篇文章的一部分:What's the React best practice for getting data that will be used for page render?

我正在使用 useState([]) 将对象添加到数组中。每个对象都有一个 firstName 和一个 lastName 值。我想将所有名字和姓氏的所有长度相加得到总字符数,这样我就可以得到每个名字的平均长度。

我目前的值是错误的:firstName (100) lastName (106)

值应该是 6 & 7

  const [players, setPlayers] = useState([]);
  const [firstNameCount, setFirstNameCount] = useState(0);
  const [lastNameCount, setLastNameCount] = useState(0);

  useEffect(() => {
    setPlayers([]);

    teams.forEach(teamId => {
      axios.defaults.headers.common['Authorization'] = authKey;

      axios.get(endPoints.roster + teamId)
        .then((response) => {
          let teamPlayers = response.data.teamPlayers;
          console.log(response.data.teamPlayers)
          setPlayers(prevPlayers => [...prevPlayers, ...teamPlayers]);
        })
        .catch((error) => {
          console.log(error);
        })
    });
  }, [teams]);

  useEffect(() => {
     players.forEach(player => {
            setFirstNameCount(prevCount => prevCount + player.firstName.length);
            setLastNameCount(prevCount => prevCount + player.lastName.length);
          })
  }, [players]);

如果我把代码改成这个

useEffect(() => {
    setPlayers([]);

    teams.forEach(teamId => {
      axios.defaults.headers.common['Authorization'] = authKey;

      axios.get(endPoints.roster + teamId)
        .then((response) => {
          let teamPlayers = response.data.teamPlayers;
          console.log(response.data.teamPlayers)
          setPlayers(prevPlayers => [...prevPlayers, ...teamPlayers]);

          teamPlayers.forEach(player => {
            setFirstNameCount(prevCount => prevCount + player.firstName.length);
            setLastNameCount(prevCount => prevCount + player.lastName.length);
          })
        })
        .catch((error) => {
          console.log(error);
        })
    });
  }, [teams]);

它大大减慢了渲染速度,我得到:firstName (7),lastName (7),这仍然是错误的。

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    我建议您将您的团队/玩家加载从组件中移出并放入与组件分开的商店中,但无论如何,为什么要将长度置于状态?为什么不在需要时从玩家状态中计算出来?

    const sum = values => values.reduce((r, v) => r + v, 0);
    const avg = values => sum(values) / values.length;
    
    const avgFirst = avg(players.map(p => p.firstName.length));
    const avgLast = avg(players.map(p => p.lastName.length));
    

    我意识到这会导致它在每次渲染时都被重新计算,但除非你的玩家列表很大,否则我希望这会是合理的性能。

    【讨论】:

    • 我不知道商店是什么...您的代码比我拥有的要优雅得多,但是当我添加代码时,我得到的数字与以前相同。名字 7 和姓氏 7。我有一个香草 javascript 版本,它给了我 6 和 7,这更可信。我也在计算最常见的情况,得到 6 和 6。应该是 4 和 6。
    • 您的玩家名称是否有前导或尾随空格?有些球员是否错过了其中一个领域?如果没有看到输入,就不可能说出正确的值是什么。向我们展示数据。
    • 这里是 1 个团队的数据示例:codesandbox.io/s/wild-darkness-5qrp9?file=/src/index.js
    • @sbaden 如果你想看一看,我在上面写了一个基本的store implementation demo。至于数字是关闭的,它可能是一个四舍五入的错误吗?你是在取平均值吗?铺地板吗?截断它?
    • 你能加入this codesandbox session吗?
    【解决方案2】:

    除了为每个增量设置状态,您可以做的是将名字和姓氏的所有长度相加,然后像这样设置状态:

    useEffect(() => {
        setPlayers([]);
    
        teams.forEach(teamId => {
          axios.defaults.headers.common['Authorization'] = authKey;
    
          axios.get(endPoints.roster + teamId)
            .then((response) => {
              let teamPlayers = response.data.teamPlayers;
              console.log(response.data.teamPlayers)
              setPlayers(prevPlayers => [...prevPlayers, ...teamPlayers]);
    
              let firstNameCount = 0;
              let lastNameCount = 0;
    
              teamPlayers.forEach(player => {
                firstNameCount += player.firstName.length;
                lastNameCount += player.lastName.length;
              })
              setFirstNameCount(prevCount => prevCount + firstNameCount);
              setLastNameCount(prevCount => prevCount + lastNameCount);
            })
            .catch((error) => {
              console.log(error);
            })
        });
      }, [teams]);
    

    如果有帮助请告诉我:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 2021-08-24
      相关资源
      最近更新 更多