useState с массивом объектов JSON, undefined не является объектом

#react-native

#react-native

Вопрос:

Я использую переменную состояния для своих данных JSON. Я получаю следующую ошибку: undefined is not an object (evaluating posts[0]) . typeof(posts) object несмотря на то, что posts является массивом. Я могу идти так глубоко, как хочу, с простым объектом JSON, но как только я получаю доступ к своим данным как к переменной состояния, React Native выдает ошибку. Код:

   const [posts, setPosts] = useState([]);
  var dataRetrieved = false;

  const getData = async () => {
    await fetchPosts();
  }

  useEffect(() => {
    if (!dataRetrieved) {
      dataRetrieved = true;
      getData();
    }
  }, []);

  const fetchPosts = useCallback(async () => {
    fetch('https://www.generic.com/api/feed', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        page: 1,
      })
    })
    .then((response)=> response.json())
    .then((json)=> {
      setPosts(json.posts);
    })
    .catch((error)=> {
      console.log(error);
    })
  });

  return (
    <FlatList contentContainerStyle={styles.gridWrap}
      ListHeaderComponent={
      <>
        <Text>
          {JSON.stringify(posts[0])}
        </Text>
        ...
  

Комментарии:

1. Где вы получаете доступ к posts [0] ?

2. @GuruparanGiritharan Я обращаюсь к нему в компоненте класса. Я обновил код, чтобы показать, как я отлаживаю.

3. Тем не менее, нет кода, имеющего posts [0], поэтому трудно понять реальную проблему

4. Я получаю ту же ошибку с показанным кодом

5. Проверьте мой ответ

Ответ №1:

В этом проблема

  <Text>
      {JSON.stringify(posts[0])}
    </Text>
  

Это происходит при вашем первом рендеринге, ваш useEffect еще не запущен, и массив не загружен из api. Когда рендеринг вызывается в первый раз, массив пуст, и доступ к первому элементу выдаст ошибку.

Исправление, которое вы можете сделать, — это показать ActivityIndicator

Нравится

 If(posts.length===0)
 return <ActivityIndicator/>
  

Или вы можете сравнить внутри рендеринга длину массива и рендеринга.

Ответ №2:

Это произошло, поскольку метод render был вызван до загрузки переменной post с данными.

вы можете решить это путем условного рендеринга, проверив, присутствуют ли данные или нет.

 { posts amp;amp; posts.length
  <Text>
   {JSON.stringify(posts[0])}
 </Text>
}
  

он проверит, является ли posts неопределенным или нет, и если это не так, он отображает текстовый компонент

Комментарии:

1. это вызовет ту же проблему, что и posts — это массив, поэтому вам нужно делать posts amp;amp; posts. длина amp;amp; <…>

2. да, поскольку он изначально содержит пустую строку, а истинное значение пустого массива равно true , вам также необходимо проверить длину.