#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
Ответ №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. Спасибо! Единственная проблема с этим заключается в том, что мне нужно отобразить в порядке массива последовательностей вместо того порядка, который мне выдает база данных.