Вывод данных массива на экран 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 шт):

Автор решения: Anvarjon

Как я вижу вы не используете 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

→ Ссылка
Автор решения: SwaD

Ваш 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>
  );
};
→ Ссылка