【问题标题】:cannot access the data inside an array无法访问数组内的数据
【发布时间】:2019-02-28 22:04:18
【问题描述】:

我在访问我从数据库中获取的状态内的数据时遇到问题, 这是我的状态:

state = {
    inputDataArr: [],
    inputDataArrTest: [
      {
        formID: 'test',
        inputArr: [1, 2, 3],
        labelArr: [4, 5, 6]
      }
    ]
  };

这是我从数据库中导入的集合:

{
    "_id": {
        "$oid": "5ba96b8ebffd923734090df4"
    },
    "inputArr": [
        "value1",
        "value2",
        "value3"
    ],
    "labelArr": [
        "label1",
        "label2",
        "label3"
    ],
    "formID": "5ba96b83bffd923734090df0",
    "__v": 0
}

这是一个包含 2 个数组的对象, 这就是我获取它的方式:

componentWillMount() {
    fetch('/api/datas')
      .then(data => data.json())
      .then(datas => {
        const filterdDatas = datas.filter(
          data => data.formID == this.props.match.params.id
        );
        this.setState(currentState => ({
          inputDataArr: [...currentState.inputDataArr, ...filterdDatas]
        }));
      });
  }

现在,当我在控制台记录 inputDataArr 和 inputDataArrTest 时,我得到一个数组,里面有一个对象, 完全相同的, 但是当我控制台登录 InputDataArrTest[0] 时,你可以在我的状态下看到,我可以看到数组和 formID, 但是当我控制台日志 inputDataArr[0] 时,我变得不确定,真的很沮丧,有人知道为什么吗?

【问题讨论】:

  • 你在哪里做console.log?在render 方法中?在没有异步数据的情况下总会有第一次渲染

标签: arrays reactjs object fetch


【解决方案1】:

在渲染中映射和进行数据操作从来都不是一个好主意,也不容易调试。

我的建议是将状态初始化为一个空数组,并调用一个方法返回映射的数据。

constructor(props) {
    super(props);
    this.state = {
        inputDataArr: []
    };
}

render() {
    const data = this.state.inputDataArr.map(...)
    return <div>{data}</div>
}

这种方式在第一次渲染之前启动状态,data 将返回一个空数组。 在componentDidMount 之后,状态将更新并使用新数据重新渲染。

作为旁注,我会在第三个then 中进行映射并将状态设置为结果本身。

快乐编码。

【讨论】:

    【解决方案2】:
     renderLabels() {
        const { inputDataArr } = this.state;
        return (
          !!inputDataArr.length &&
          inputDataArr[0].labelArr.map((label, index) => (
            <th key={index}>{label}</th>
          ))
        );
      }
    

    条件渲染解决了我的问题

    【讨论】:

    • 还有,调试会很麻烦
    • .length 永远不会是 -n 所以它要么是 0 或以上。因此没有理由强制使用布尔值。 inputDataArr.length &amp;&amp; ... 应该足够了。顺便说一句,你的问题缺少很多重要的细节(比如你的render方法)
    【解决方案3】:

    我不确定你在哪里运行console.log,但setState 有一个回调方法,你可以在实际数据更新后运行:

    this.setState(currentState => ({
      inputDataArr: [...currentState.inputDataArr, ...filterdDatas]
    }), () => {
        // this is the callback for setState, you can access the updated data
      console.log(inputDataArr);
    }); 
    

    注意如果您在render 中运行console.log,请记住第一个render 调用将始终在获取异步数据之前运行。

    注意 #2 Do not use componentWillMount,尤其不能用于获取数据。
    Use componentDidMount instead

    【讨论】:

    • 感谢您的评论,我复制了您的代码并更改为 DidMount,但我仍然得到 inputDataArr is undefined
    • inputDataArrundefined 还是 inputDataArr[0] 未定义?
    • 是的,由于另一个堆栈溢出帖子,我发布了一个对我有用的解决方案,感谢您的帮助!
    【解决方案4】:
    1. 您在使用...filteredDatas 之前测试过filteredDatas 吗?也许它不是一个数组和结果到其他东西或一个空数组。
    2. 您确定this.props.match.params.id 已定义且等于formID 属性吗?
    3. 如果它只存在一个具有唯一formID 的对象,为什么不使用Array#find 而不是Array.filter,然后使用更新您的状态

      this.setState(prevState => ({ 数据Arr:过滤数据? prevState.dataArr.concat([filteredDatas]) : prevState.dataArr // 这里使用 Array#find,filteredDatas 为 null 或对象不是 Array });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 2017-12-31
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      相关资源
      最近更新 更多