useState, похоже, не может правильно отобразить массив

#javascript #reactjs #react-hooks

#javascript #reactjs #реагирующие хуки

Вопрос:

У меня есть простая страница, которая в fdoes немного больше, но я сократил ее до проблемного кода. Я извлекаю данные из облачного хранилища Firestore. У меня есть одна коллекция данных, которая представляет последовательность объектов. Другая коллекция — это сами объекты:

 import React, { useState } from "react";

const App = () => {
  const boardSequence = ["boardid2", "boardid1"];
  const boardData = [
    {
      boardid1: {
        boardValue: "Sales",
        boardColor: "#003c8a",
        boardDifference: "#FFFFFF"
      }
    },
    {
      boardid2: {
        boardValue: "Follow Ups",
        boardColor: "#000000",
        boardDifference: "#FFFFFF"
      }
    }
  ];

  const [boards] = useState(boardData);
  const [sequence] = useState(boardSequence);
  return (
    <div>
      {sequence.map((boardId, index) => {
        return <p key={index}>{boards[boardId].boardValue}</p>;
      })}
    </div>
  );
};
export default App;
  

Я начинаю с отображения через массив sequence, затем пытаюсь отобразить значения из массива board, но получаю ошибку

Не удается прочитать свойство ‘boardValue’ из undefined

РЕДАКТИРОВАТЬ: Вот код, который я использую для получения данных. Похоже, реальный вопрос в том, как мне вывести это из массива в объект, который можно прочитать?

     const promise1 = appBase.firestore().collection("workflow").get();
    const promise2 = appBase.firestore().collection("boards").get();

    Promise.all([promise1, promise2])
      .then((snapshot) => {
        // console.log(snapshot[0].docs.data().boardIds);
        const newBoardIds = snapshot[0].docs.map((doc) => {
          return doc.data().boardIds;
        });
        setBoardIds(newBoardIds[0]);

        const newBoards = snapshot[1].docs.map((doc) => {
          return {
            [doc.id]: {
              boardValue: doc.data().boardValue,
              boardColor: doc.data().boardColor,
              boardDifference: doc.data().boardDifference,
            },
          };
        });

        console.log(newBoards);
        setBoards(newBoards);
        // setSettings({ ...settings, dataLoaded: true });
        setDataLoaded(true);
      })
      .catch((error) => {
        console.log("error returned on boards: "   error);
      });
  

Комментарии:

1. boardData предполагается, что это массив? похоже, что это должен быть объект с ключами, а не массив объектов с одним ключом в каждом

Ответ №1:

Вы должны преобразовать boardData из массива в объект. В демо-версии я использую reduce для достижения этого

 const [boards] = useState(
  boardData.reduce((acc, obj) => ({ ...acc, ...obj }), {})
);
  

Демонстрация Codesandbox

Редактировать потрясающе-chandrasekhar-cngnx

Ответ №2:

Здесь,

 {sequence.map((boardId, index) => {
  return <p key={index}>{boards[boardId].boardValue}</p>;
})}
  

boards является массивом и, следовательно, ищет целочисленный индекс. Если вы хотите выполнить поиск по ключу, то ваши данные должны быть такого формата,

 const boardData = {
    boardid1: {
      boardValue: "Sales",
      boardColor: "#003c8a",
      boardDifference: "#FFFFFF",
    },
    boardid2: {
      boardValue: "Follow Ups",
      boardColor: "#000000",
      boardDifference: "#FFFFFF",
    },
};
  

Комментарии:

1. Я полагаю, моя проблема в том, как мне получить его в этом формате? То, что вы видите, — это формат, который предоставляет мне Firebase, и я не уверен, как это изменить.

Ответ №3:

Вы выполняете цикл по массиву последовательностей строк; Я думаю, вы хотели выполнить цикл по boards; который представляет собой массив объектов. Вот так:

 import React, { useState } from "react";

const App = () => {
  const boardSequence = ["boardid2", "boardid1"];
  const boardData = [
    {
      boardid1: {
        boardValue: "Sales",
        boardColor: "#003c8a",
        boardDifference: "#FFFFFF"
      }
    },
    {
      boardid2: {
        boardValue: "Follow Ups",
        boardColor: "#000000",
        boardDifference: "#FFFFFF"
      }
    }
  ];

  const [boards] = useState(boardData);
  const [sequence] = useState(boardSequence);
  return (
    <div>
      {boards.map((boardId, index) => {
        return <p key={index}>{boards[boardId].boardValue}</p>;
      })}
    </div>
  );
};
export default App;
  

Комментарии:

1. Спасибо! Единственная проблема с этим заключается в том, что мне нужно отобразить в порядке массива последовательностей вместо того порядка, который мне выдает база данных.