Объекты недействительны в качестве дочерних элементов React (найдено: объект с ключами {_id, date, createdAt, updatedAt, __v})

Я получаю следующую ошибку, когда пытаюсь отобразить объект ({день} см. компонент реакции ниже), поступающий из базы данных:

Ошибка: объекты недействительны в качестве дочернего элемента React (найдено: объект с ключами {_id, дата, createdAt, updatedAt, __v}). Если вы хотели сделать коллекция дочерних элементов, вместо этого используйте массив.

Рассматриваемый объект выглядит следующим образом:

{
  "_id": "5fdf554b88f52f520c93a16e",
  "date": "2020-12-20T10:00:00.133Z",
  "createdAt": "2020-12-20T13:44:43.934Z",
  "updatedAt": "2020-12-20T13:44:43.934Z",
  "__v": 0
}

И следующий мой код:

Маршрутизатор:

dayRouter.get(
  '/:id',
  expressAsyncHandler(async (req, res) => {
    const day = await Day.findOne({ _id: req.params.id })
    if (day) {
      res.send(day);
    } else {
      res.status(404).send('Booking Not Found.');
    }
  })
);
export default dayRouter;

Редукс-действие:

export const detailsDate = (dayId) => async (dispatch) => {
  try {
    dispatch({ type: DATE_DETAILS_REQUEST, payload: dayId });
    const { data } = await Axios.get(`/api/day/${dayId}`);
    dispatch({ type: DATE_DETAILS_SUCCESS, payload: data });
  } catch (error) {
    dispatch({
      type: DATE_DETAILS_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message,
    });
  }
};

Redux-редуктор:

export function dateDetailsReducer(
    state = {loading: true}, action) {
    switch (action.type) {
      case DATE_DETAILS_REQUEST:
        return { loading: true };
      case DATE_DETAILS_SUCCESS:
        return { loading: false, day: action.payload };
      case DATE_DETAILS_FAIL:
        return { loading: false, error: action.payload };
      default:
        return state;
    }
  }

Реагирующий компонент:

import { useDispatch, useSelector } from 'react-redux';
import { detailsDate } from '../actions/dateAction';

function BookingConfirmationScreen(props) {  

  const dayId = props.match.params.id;

  const dateDetails = useSelector((state) => state.dateDetails); //from Redux Store
  const { day } = dateDetails;

  const dispatch = useDispatch();
  useEffect(() => {

      dispatch(detailsDate(dayId));
    return () => {};
  }, [day,dispatch, dayId]);

  return (
    <h1> Booking {day}</h1>
  )
}

export default BookingConfirmationScreen;

То, что мне нужно отобразить, на самом деле {day.date}, но я понимаю, что этот день на самом деле не определен. Именно тогда я понял, что есть проблема с {day}

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
1 252
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

 const { day, loading } = dateDetails;
.
.
.

затем сделайте это, когда вы вернетесь:

if (loading)
return <div> loading.. </div>
 return (
    <h1> Booking {day.date}</h1>
  )

Это правда. Большое спасибо, это сработало. Я новичок и пытаюсь учиться. Могу ли я спросить вас, что вы имели в виду, говоря «вы получаете эти данные с сервера, поэтому рендеринг компонента выполняется быстрее, чем асинхронный вызов»? Я использую асинхронность в маршрутизаторе и действии. Спасибо

Francesco 20.12.2020 16:23

Каждый раз, когда вы делаете вызов (запрос) к серверу, вы ждете ответа, и эта функция является асинхронной, асинхронный код принимает операторы за пределами основного потока программы, позволяя коду после асинхронного вызова выполняться немедленно без ожидания, в вашем случае компонент рендерится, не дожидаясь получения данных с сервера, поэтому сначала переменная day не определена (данные еще не получены). Я надеюсь, вы понимаете. Вот хорошая документация по этому поводу: rowanmanning.com/posts/javascript-for-beginners-async

leonae 20.12.2020 16:42

Это еще лучше: blog.bitsrc.io/…

leonae 20.12.2020 16:48

Другие вопросы по теме