ReactJS: функциональный компонент с реквизитом, определенным как массив, но видимым как объект

При рендеринге <MyComponent {...docs} /> я сохранил следующую ошибку:

TypeError: docs.map is not a function

Вот как я визуализирую <MyComponent /> из компонента на основе родительского класса:

import * as React from 'react'
import IDoc from '../types/IDoc'

class Doc extends React.Component
{
   public render()
   {
      const docs : IDoc[] = Defs.getDef();
      // Example of map working (not doing anything just for an example)
      docs.map(x => x);

      return (
         <div>
            <MyComponent {...docs} />
         </div>
      )
   }
}

По какой-то причине, когда я передаю массив docs функциональному компоненту <MyComponent/>, он не отображается как массив. Мне нужно преобразовать его в массив перед использованием .map(), которого я бы предпочел избежать:

import * as React from 'react'
import IDoc from '../types/IDoc'

// docs is an array isn't?
function MyComponent(docs : IDoc[] )
{

   if (Array.isArray(docs) === false)
   {
     //Its not seen as an array so falls into this 
      return (
         <div>
            { Object.keys(docs).map((index) => {
               const doc : IDoc = docs[index];
               const name = doc.name;
               return (
                  <div>{name}</div>
               )
               })
            }
         </div>
      )
   }else
   {
      // what I expected to work but it throws the error
      return (
         <div>
            { docs.map((doc) => {
               return (
                  <div>{doc.name}</div>
               )
               })
            }
         </div>
      )
   }
}

Я думал, что, когда я определял реквизиты документов как IDocs[], это было бы видно как массив из-за квадратных скобок.

Приведенный выше обходной путь работает, но, очевидно, я не хочу делать это каждый раз, когда использую функцию массива, например map(). Я новичок в React, поэтому буду признателен за любые указатели. Я использовал создать-реагировать-приложение мое-приложение --scripts-версия = реагировать-скрипты-тс на случай, если это поможет.

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

Ответы 1

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

В настоящее время вы распространение элементы массива docs в props из MyComponent, выполнив следующие действия:

<MyComponent {...docs} />

Подумайте о том, чтобы пересмотреть свою функцию MyComponent, чтобы доступ к docs осуществлялся через ее собственную опору. Это будет означать доступ к docs через объект props, переданный функциональному компоненту MyComponent следующим образом:

/* Add props argument, where docs array is an entry of props */
function MyComponent(props : { docs : IDoc[] }) {
    const { docs } = props;

    /* You can now use docs as before 
    if (Array.isArray(docs) === false)
    */
}

Это изменение потребует, чтобы в вашем компоненте Doc компонент MyComponent отображался путем передачи docs в качестве реквизита (а не распространения элементов массива docs непосредственно в реквизиты MyComponent), выполнив следующие действия:

  return (
     <div>
        {/* Don't spread docs, but instead pass docs via docs prop */}
        <MyComponent docs = {docs} />
     </div>
  )

Надеюсь это поможет!

Большое спасибо @DacreDenny, я преобразовал, и это сработало отлично. Вы ответили в течение 12 минут после того, как я опубликовал вопрос, мне потребовалось больше времени, чтобы написать вопрос, и еще больше времени, чтобы попытаться решить его самостоятельно!

user3210699 07.04.2019 00:20

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