не может получить доступ к данным внутри массива - PullRequest
0 голосов
/ 25 сентября 2018

У меня проблемы с доступом к данным из моего состояния, которые я получаю из своей базы данных, это мое состояние:

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
}

, который является объектом с двумя массивами в нем, вот как я его получаю:

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] я получаю неопределенный, действительно разочаровывает, кто-нибудь знает почему?

Ответы [ 4 ]

0 голосов
/ 26 сентября 2018

Отображение и выполнение манипулирования данными внутри рендера никогда не является хорошей идеей и не легко отладить.

Мое предложение состоит в том, чтобы инициализировать состояние пустым массивом и вызвать метод для возврата сопоставленногоdata.

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

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

Таким образом, состояние инициируется перед первым рендерингом, и data возвращает пустой массив.После componentDidMount состояние будет обновлено и будет выполнено повторное рендеринг с новыми данными.

В качестве примечания я бы сделал отображение в третьем then и установил бы состояние на сам результат.

Счастливое кодирование.

0 голосов
/ 25 сентября 2018

Я не уверен, где вы используете 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);
}); 

Примечание Если вы запускаете console.log в render, имейте в виду, что первый вызов render всегда будет выполняться до получения асинхронных данных.

Примечание # 2 Не использовать componentWillMount вообще, особенно для извлечения данных.
Использовать componentDidMount вместо .

0 голосов
/ 25 сентября 2018
 renderLabels() {
    const { inputDataArr } = this.state;
    return (
      !!inputDataArr.length &&
      inputDataArr[0].labelArr.map((label, index) => (
        <th key={index}>{label}</th>
      ))
    );
  }

условный рендеринг решил мою проблему

0 голосов
/ 25 сентября 2018
  1. Вы проверяли filteredDatas перед использованием ...filteredDatas?Может быть, это не массив, а результат для другой вещи или пустой массив.
  2. Вы уверены, что this.props.match.params.id определено и равно свойству formID?
  3. Если оносуществует только один объект с уникальным formID, почему бы вам не использовать Array#find вместо Array.filter, а затем обновить свое состояние с помощью

    this.setState (prevState => ({dataArr: FilterDatas? prevState.dataArr.concat ([FilterDatas]): prevState.dataArr // Здесь с Array # find, FilterDatas имеет значение null или объект не является массивом});

...