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

#reactjs #typescript

#reactjs ( реакция ) #машинописный текст #reactjs #typescript

Вопрос:

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

Ошибка типа: docs.map не является функцией

Вот как я выполняю рендеринг <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>
      )
   }
}
  

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

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

Ответ №1:

В настоящее время вы распространяете элементы docs массива в props of 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>
  )
  

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

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

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