Вывод данных массива на экран React
У меня есть React приложение. В компонента страницы водителя (DriverWay) я получил все заказы с базы данных и записал их в orderList. Я пытаюсь вывести данные на экран через компонент Order, но не получается. Массив не пустой, я проверял
DriverWay:
const orderList = [];
const DriverWay = () => {
const listen = onAuthStateChanged(auth, (user) => {
if (user) {
setUid(user.email.split('@')[0]);
}
});
const db = getDatabase();
const dbRef = ref(db, 'orders/');
function handleOnClick() {
onValue(
dbRef,
(snapshot) => {
snapshot.forEach((childSnapshot) => {
orderList.push(childSnapshot.val());
});
},
{
onlyOnce: true,
}
);
}
handleOnClick();
orderList.map((item) => console.log(item));
return (
<div className={styles.driver__way__block}>
<MapWithRoute />
<Button
type="submit"
onClick={handleOnClick}
width={19.9375}
height={3.6875}
bgc="FFE500"
btnText="Показать заказы"
btnTextColor="FFF"
/>
<div
style={{
position: 'absolute',
width: '100vw',
height: '100vh',
zIndex: 9999999,
backgroundColor: '#fff',
top: 0,
}}
>
{orderList.map((order) => (
<Order
key={order}
nowGeo={order.nowGeolocation}
endGeo={order.endGeolocation}
uid={order.uid}
/>
))}
</div>
</div>
);
};
Order:
const Order = (props) => {
return (
<div>
<h1>Now geo: {props.nowGeo}</h1>
<h2>End geo: {props.endGeo}</h2>
</div>
);
};
export default Order;
App.jsx:
function App() {
return (
<div className="App">
<Routes>
<Route path="/driver-way" element={<DriverWay uid={driverId} />} />
</Routes>
</div>
);
}
export default App;
Получение данных и запись я упустил. Также пробовал просто вывести элементы массива с помощью .map (orderList.map((item) => console.log(item));). Логи пустые, на экране ничего
Ответы (2 шт):
Как я вижу вы не используете State
Используйте State чтобы компонент обновлялся при изменении массива
const [orderList, setOrderList] = useState([])
При выполнении запроса нужно вызвать setOrderlist(Новый массив) чтобы компонент перерендерился
Используйте useEffect для разового обновления компонента:
useEffect(function, [])
Внутри функции напишите fetch и setOrderList для state
**Правка
Вынесите этот кусок кода в App.jsx:
const listen = onAuthStateChanged(auth, (user) => {
if (user) {
setUid(user.email.split('@')[0]);
}
});
const db = getDatabase();
const dbRef = ref(db, 'orders/');
const [orderList, setOrderList] = useState([])
function handleOnClick() {
onValue(
dbRef,
(snapshot) => {
snapshot.forEach((childSnapshot) => {
setOrderList(...orderList,childSnapshot.val());
});
},
{
onlyOnce: true,
}
);
}
handleOnClick();
Передайте в DriverWay orderList как props
Ваш orderList должен быть переменной состояния компонента, в таком случае React сможет отслеживать изменения и перерисовывать данные на странице.
Так же, инициализацию соединения с БД(или что это) лучше убрать из компонента, иначе каждое изменение данных внутри компонента будет инициироваться новое соединение.
В дополнение, вызов функции handleOnClick внутри компонента приведет к повторному запросу данных, повторному вызову функции и далее все зациклится.
const db = getDatabase();
const dbRef = ref(db, 'orders/');
const DriverWay = () => {
// Создаем переменную состояния
const [orderList, setOrderList] = useState([]);
// Функция вызывается по клику
function handleOnClick() {
onValue(
dbRef,
(snapshot) => {
const newOrderList = []; // Создаем новый массив
snapshot.forEach((childSnapshot) => {
// Пушим данные
newOrderList.push(childSnapshot.val());
});
// Сохраняем данные в переменную состояния, что приведет к перерисовке компонента
setOrderList(newOrderList);
},
{
onlyOnce: true,
}
);
}
return (
<div className={styles.driver__way__block}>
<MapWithRoute />
<Button
type="submit"
onClick={handleOnClick}
width={19.9375}
height={3.6875}
bgc="FFE500"
btnText="Показать заказы"
btnTextColor="FFF"
/>
<div
style={{
position: 'absolute',
width: '100vw',
height: '100vh',
zIndex: 9999999,
backgroundColor: '#fff',
top: 0,
}}
>
{orderList.map((order) => (
<Order
key={order}
nowGeo={order.nowGeolocation}
endGeo={order.endGeolocation}
uid={order.uid}
/>
))}
</div>
</div>
);
};