【问题标题】:ReactJS - Map for state arrayReactJS - 状态数组的映射
【发布时间】:2020-04-22 10:41:40
【问题描述】:

我正在创建一个金融网站,但遇到了麻烦,因为 .map 没有在状态数组上执行。这两天我一直在敲墙。我在想这真的很小

这是我为填充数组和设置状态而进行的GET 调用。

.then(() => {
            var transactions = [];
            axios.get("http://localhost:5000/transactions").then(res => {
                res.data.transactions.transactions.forEach(function(txn, idx) {
                    transactions.push({name: txn.name, amount: txn.amount, date: txn.date});
                    // item.push("hey");
                });
            });
            this.setState({transactions: transactions, balance: content.balance});
        }).catch(err => console.log(err));

那么我的渲染方法是这样的

render() {
        var list = this.state.transactions.map((item, id) => {
            return (
                <VerticalTimelineElement
                    className="vertical-timeline-element--work"
                    contentStyle={{ background: 'rgb(33, 150, 243)', color: '#fff' }}
                    contentArrowStyle={{ borderRight: '7px solid  rgb(33, 150, 243)' }}
                    date={item.date}
                    iconStyle={{ background: 'rgb(33, 150, 243)', color: '#fff' }}
                    key={id}
                >
                    <h3 className="vertical-timeline-element-title">{item.name}</h3>
                    <h4 className="vertical-timeline-element-subtitle">${item.amount}</h4>
                </VerticalTimelineElement>
            );
        });

        return (
            <VerticalTimeline>
                {list}
            </VerticalTimeline>
        );
    }

【问题讨论】:

  • 你有什么问题?
  • 没有任何东西被渲染,即使事务数组中有项目,map 方法也没有运行。
  • 请展示地图最初的样子
  • 我不明白你的意思。这是确切的代码。@cr05s19xx
  • 另外,我注意到您没有在.then 块中更新您的状态。您应该可能将您的电话转移到axios.get().then() 内的setState()

标签: javascript arrays reactjs web


【解决方案1】:

尝试使用 React 钩子。已经忘记了旧方法。

import React, { useState } from 'react';
...
const [transactions, setTransactions] = useState(() => {
   const temp = [];
   axios.get("http://localhost:5000/transactions").then(res => { 
      res.data.transactions.transactions.forEach(function(txn, idx) {
          temp.push({name: txn.name, amount: txn.amount, date: txn.date});
      });
   });
   return temp;
});

【讨论】:

    【解决方案2】:

    由于axios.get 异步运行,对setState 的调用可能会在transaction 中包含任何项目之前运行。对axios.get 的调用应该上移到axios.get().then() 块中:

    .then(() => {
        var transactions = [];
        axios.get("http://localhost:5000/transactions").then(res => {
            res.data.transactions.transactions.forEach(function(txn, idx) {
                transactions.push({name: txn.name, amount: txn.amount, date: txn.date});
                // item.push("hey");
            });
            this.setState({transactions: transactions, balance: content.balance});
        });
    }).catch(err => console.log(err));
    

    另外,请注意,使用数组中项的索引作为键不是最佳做法,如果重新排序数组或添加或删除项,可能会导致意外结果。根据docs

    密钥应该是稳定的、可预测的和唯一的。不稳定的键(如 Math.random() 生成的键)会导致不必要地重新创建许多组件实例和 DOM 节点,这可能会导致性能下降和子组件中的状态丢失。

    【讨论】:

    • 这应该是错误的,因为您在 foreach 函数中反复调用 setState。事务数组引用不会更改,因此并非所有更新都可能反映在显示屏上。
    • 我不小心把电话移到setState 一行太高了!你是对的:setState 应该在forEach 之后调用,我现在已经修复了我的代码。谢谢!
    【解决方案3】:

    你可以试试这个:

    const {transactions: collection } = res.data.transactions
    const transactions = collection.map(({ name, amount, date }) => ({ name, amount, date }));
    
    this.setState({transactions, balance: content.balance});
    

    我也认为你需要在 .then 块内移动它。

    虽然同意钩子会更好,但试试这个。

    让我知道你过得怎么样!

    【讨论】:

      猜你喜欢
      • 2017-12-26
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 2020-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      相关资源
      最近更新 更多