Я пытаюсь перебрать объекты, которые я получаю от вызова API. Но после установки данных в состояние setNodesData и получения данных из nodesData, но когда я пытаюсь это сделать, я получаю сообщение об ошибке говоря: TypeError: Object.entries requires that input parameter not be null or undefined in React Native

Я также пробовал for(const i in nodesData), но все равно получаю сообщение об ошибке expression expected

useEffect(() => {
    if (apiHeaders) {
      axios
        .get(
          "https://test-myways-anfhsya-asq.myways.in/api/****",
          {
            headers: apiHeaders,
          }
        )
        .then((res) => {
          console.log("API Call")
          console.log(res?.data);
          setNodesData(res?.data);
        })
        .catch((err)=>{console.log("error:",err)});
    }
  }, [apiHeaders]);

  return (
    
  
      {
      Object?.entries(nodesData).forEach((i) => (
        <View style={{ padding: 5 }}>
          <View
            style={{
              flexDirection: "row",
              alignItems: "center",
            }}
          >
            <TouchableOpacity
               onPress={(props) => props.navigation.navigate("CoursesPlaylistScreen")}
              style={{
                flexDirection: "row",
                alignItems: "center",
                justifyContent: "space-between",
                flex: 1,
              }}
            >
              <View
                style={{
                  flexDirection: "row",
                  justifyContent: "space-between",
                  flex: 1,
                }}
              >
                <Text
                  style={{
                    fontSize: 16,
                    color: "#000000",
                    fontWeight: "bold",
                  }}
                >
                  {i}
                </Text>
              </View>
            </TouchableOpacity>
          </View>

Данные:

{
    "week1": {
        "content": [
            {
                "moduleName": "HTML Crash course",
                "moduleVideos": [
                    {
                        "title": "HTML Crash Course For Absolute Beginners",
                        "link": "https://youtu.be/*****",
                        "duration": "01:00:42"
                    }
                ]
            },
            {
                "moduleName": "CSS Crash course",
                "moduleVideos": [
                    {
                        "title": "CSS Crash Course For Absolute Beginners",
                        "link": "https://youtu.be/*****",
                        "duration": "01:25:11"
                    }
                ]
            },

Я хочу получить только недели, но получаю ошибки и не знаю, как это сделать.

1
Harsh Mishra 24 Окт 2021 в 10:38
Измените свое сообщение, чтобы оно содержало только минимальный воспроизводимый пример, необходимый для поиска проблемы. Прикрепление всего файла - более сотни строк, возможно, неактуального кода - только усложнит поиск проблемы.
 – 
Eldar B.
24 Окт 2021 в 10:46
@EldarB. Ой. Хорошо, спасибо, я отредактировал сообщение.
 – 
Harsh Mishra
24 Окт 2021 в 10:49

2 ответа

Лучший ответ

Проблема

Проблема, скорее всего, возникает при первоначальном рендеринге. Вы пытаетесь преобразовать undefined в массив записей объекта.

const [nodesData, setNodesData] = useState(); // <-- undefined initial state!

...

Object?.entries(nodesData).map( ... // <-- blows up with error

Контрольная работа

const nodesData = undefined;
console.log(Object.entries(nodesData)); // error
const nodesData = {};
console.log(Object.entries(nodesData)); // []

.map против .forEach

Ваше редактирование, когда вы изменили Object?.entries(nodesData).map( ... на Object?.entries(nodesData).forEach( ..., ничего не вернет для обработки, поскольку .forEach технически является недействительным возвратом. Верните это изменение, чтобы использовать .map.

Кроме того, поскольку каждое «значение» записи по-прежнему является объектом, вам необходимо выбрать значения объекта, которые вы хотите отобразить. Если есть какие-либо вложенные массивы, их также необходимо сопоставить с JSX.

Решение

Укажите допустимое начальное состояние. Пустого объекта должно хватить.

const [nodesData, setNodesData] = useState({});

И если случайно, состояние nodesData позже станет неопределенным, используйте нулевую проверку или укажите запасное значение.

  • nodesData && Object.entries(nodesData).map( ...
  • Object.entries(nodesData || {}).map( ...

Хотя в идеале вы должны поддерживать инвариант состояния, чтобы, по крайней мере, всегда быть определенным объектом.

Вывести недельные ключи nodesData

Если вам просто нужны ключи, вы можете:

  • Отобразите ключ из записей ( напомним, что записи представляют собой массив пар ключ-значение, то есть [[key1, value1], [key2, value2], ...] )

     Object.entries(nodesData).map(([week, data]) => (
       <View style={{ padding: 5 }}>
         ...
           <Text .... >
             {week} // "week1", "week2", etc...
           </Text>
         ...
       </View>
    
  • Используйте Object.keys, чтобы получить массив только ключей

     Object.keys(nodesData).map((week) => (
       <View style={{ padding: 5 }}>
         ...
           <Text .... >
             {week} // "week1", "week2", etc...
           </Text>
         ...
       </View>
    
1
Drew Reese 24 Окт 2021 в 11:20
Я применил это, и сейчас я не получаю ошибок, но и недель не получаю. Не могли бы вы мне помочь. Как я могу получить данные за несколько недель? Мне нужно что-то изменить в {i}?
 – 
Harsh Mishra
24 Окт 2021 в 11:04
1
Да, я также добавил примечание об этом. Каждый элемент, который вы отображаете, по-прежнему является объектом, поэтому вам нужно решить, какую часть каждого «недельного» объекта вы хотите визуализировать. Например, i.content - это массив, поэтому вам нужно будет сопоставить этот массив с JSX, и для каждого элемента в этом массиве есть строка moduleName и массив `moduleVideos`, которые могут быть отображены.
 – 
Drew Reese
24 Окт 2021 в 11:11
1
Понимаю, тоже довольно тривиально. См. Обновленный ответ в разделе решения.
 – 
Drew Reese
24 Окт 2021 в 11:19
1
Оно работает. На самом деле большое спасибо за вашу помощь.
 – 
Harsh Mishra
24 Окт 2021 в 11:26

Изменить:

… Object?.entries(nodesData).map((i) => ( …

Кому:

… nodesData && Object.entries(nodesData).map((i) => ( …
2
Michael Bahl 24 Окт 2021 в 10:49