#javascript #reactjs
Вопрос:
У меня есть компонент в react, который извлекает историю, написанную пользователем из бэкенда. Затем я сохраняю json в storyState
, и когда я регистрирую его, там находятся необходимые свойства, такие как «заголовок», но когда я пытаюсь получить доступ к названию свойства, я получаю эту ошибку:
TypeError: Cannot read properties of undefined (reading 'title')
Вот код:
import { useState, useEffect } from 'react';
import styled from 'styled-components';
export const StoryPage = () => {
const [storyState, setStoryState] = useState({
story: {},
isLoaded: false,
error: null,
});
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const id = urlParams.get('storyid');
useEffect(() => {
fetch('http://localhost:5000//getstory?storyid=' id)
.then((response) => {
console.log('response is', response);
if (response.status !== '200') {
let err = Error;
err.message = 'Invalid response code: ' response.status;
setStoryState({ error: err });
}
return response.json();
})
.then((json) => {
console.log('json is', json);
setStoryState({
story: json.story,
isLoaded: true,
});
});
}, []);
console.log('storystate.story', storyState.story);
return (
<>
<h1>test</h1>
<h1>{storyState.story.title}</h1>
</>
);
};
export default StoryPage;
Я проверил StackOverflow и попробовал использовать JSON.parse
, но, к сожалению, это не сработало.
Когда я это делаю < h1 >{storyState.story}</ h1 >
, я получаю весь объект в строковой форме со всеми свойствами, как и ожидалось.
Вот моя консоль:
Комментарии:
1. При первом рендеринге он еще недоступен , поэтому вы помещаете загрузчик или рендеринг null, а затем после того, как он будет доступен, показываете данные, которые вы пытаетесь отобразить …. Просто
if(!data)return null;return(whaterver u want next );
чтобы понять это, попробуйте зарегистрировать storyState.story внутри return ….
Ответ №1:
Проблема в этой строке —
if (response.status !== "200") {
}
Это должно быть 200 вместо «200». Вы можете проверить console.log("response is", response);
, что это число 200, а не строка.
Примечание: Всегда используйте приведенную ниже конструкцию для задания состояния объектов —
{ ...previousState, { newkey: newvalue } }
Вышесказанное использует предыдущие значения объекта и заменяет их новыми значениями.
Комментарии:
1. Большое вам спасибо, это сработало для меня! С этого момента я буду использовать эту конструкцию для задания состояния!
Ответ №2:
При самом первом рендеринге данные недоступны, следовательно, вы должны выполнять рендеринг <h1>{storyState.story.title}</h1>
только тогда, когда данные получены и доступны, поэтому добавьте оператор if в рендеринг или вы также можете использовать дополнительную цепочку
<h1>{storyState?.story?.title}</h1>
Комментарии:
1. Спасибо и тебе, Тарун, твой ответ действительно сработал!
Ответ №3:
Может возникнуть задержка при извлечении данных с сервера, вы можете добавить в него загрузчик, который проверяет, есть ли значение storySTate
, а затем визуализирует данные, или добавить другую функцию useEffect, которая регистрирует файл всякий раз, когда происходит изменение в цепочке storyState, например:
useEffect(() => {
console.log(storyState.story)
}, [storyState])