ReactJS — чтение данных json

#javascript #json #reactjs

#javascript #json #reactjs

Вопрос:

Я пытаюсь заполнить данные таблицы путем импорта json. Однако, получаю ошибку ниже: неперехваченное инвариантное нарушение: объекты недопустимы в качестве дочернего элемента React (найдено: объект с ключами { список }). Если вы хотели отобразить коллекцию дочерних элементов, используйте вместо этого массив.


Ниже приведен код, который я использую:

 import reg from "./data/reg.json";

class TableRow extends Component {
  render() {
    const { data } = this.props;

    const list = data.map(adata => {
      return (
        <tr>
          <React.Fragment>
            <td key={adata.FName}>{adata.FName}</td>
            <td key={adata.LName}>{adata.LName}</td>
            <td key={adata.Age}>{adata.Age}</td>
          </React.Fragment>
        </tr>
      )//return
    })//regionslist

    return (
      { list }
    );//return
  } //render
} //class


class DTable extends Component {
  render() {
    return (
      <Table striped bordered hover>
        <TableHeader />
        <tbody>
          <TableRow data={this.props.data} />
        </tbody>
      </Table>
    );
  }
}

class DataTable extends Component {
  render() {
    return (
      <DTable data={reg} />
    );//return
  } //render
}  

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

1. Можем ли мы взглянуть на этот файл json?

2. [{ «FName»: «John», «LName»: «M», «Age»: «42» }, { «FName»: «Michael», «LName»: «S», «Age»: «30» }]

Ответ №1:

Проблема

Я воссоздал вашу настройку, пытаясь воспроизвести вашу ошибку. Вы можете увидеть, что я воспроизвел здесь: Stackblitz. Проблема, похоже, заключается в том, что ваша карта создает несколько строк таблицы, но нет родительского элемента для их переноса, что требуется JSX.


Решение

Это можно исправить, обернув {list} внутри React.Fragment :

 class TableRow extends Component {
  render() {
    const { data } = this.props;

    const list = data.map(adata => {
      return (
        <tr>
          <td key={adata.FName}>{adata.FName}</td>
          <td key={adata.LName}>{adata.LName}</td>
          <td key={adata.Age}>{adata.Age}</td>
        </tr>
      )//return
    })//regionslist

    return (
      <React.Fragment>
      { list }
      </React.Fragment>
    );//return
  } //render
} //class
  

Добавление React.Fragment вокруг элементов списка решило проблему. Вы можете увидеть рабочее решение здесь: Stackblitz


Альтернативы

Начиная с React 16.2 (Подробнее) у вас также есть возможность возвращать пустые теги JSX вместо ввода React.Фрагмент. Решение, приведенное выше, будет выглядеть следующим образом:

 class TableRow extends Component {
  render() {
    const { data } = this.props;

    const list = data.map(adata => {
      return (
        <tr>
          <td key={adata.FName}>{adata.FName}</td>
          <td key={adata.LName}>{adata.LName}</td>
          <td key={adata.Age}>{adata.Age}</td>
        </tr>
      )//return
    })//regionslist

    return (
      <>
      { list }
      </>
    );//return
  } //render
} //class
  

Наконец, также возможно возвращать массив элементов начиная с React 16.0. Если вы решите сделать это, приведенный выше код будет выглядеть следующим образом:

 class TableRow extends Component {
  render() {
    const { data } = this.props;

    const list = data.map(adata => {
      return (
        <tr>
          <td key={adata.FName}>{adata.FName}</td>
          <td key={adata.LName}>{adata.LName}</td>
          <td key={adata.Age}>{adata.Age}</td>
        </tr>
      )//return
    })//regionslist

    return [list];//return
  } //render
} //class
  

Однако ограничение этой опции заключается в том, что к элементам должен быть добавлен ключ, поскольку в противном случае React выдаст это предупреждение в консоли:

Предупреждение: у каждого дочернего элемента в списке должен быть уникальный «ключевой» реквизит.

Обратите внимание, что даже если вы опустите этот ключ, он все равно будет отображаться правильно.

Ответ №2:

Изначально существовало ограничение в React том, что вы можете возвращать только один элемент из функции рендеринга, но после этого оно было изменено React 16 , теперь вы можете возвращать массив элементов.

В вашем случае вы пытаетесь создать массив элемента, не упоминая, что это массив, из-за которого вы должны его сгруппировать с помощью Fragment .

Эта проблема может быть решена двумя способами:

  1. Перенос массива внутрь Fragment или любого другого элемента контейнера (но в этом случае он добавит один дополнительный узел в DOM, который является плохим, и для решения этой проблемы Fragment's вводятся. более подробную информацию смотрите здесь:https://reactjs.org/docs/fragments.html )

    return (
    <React.Fragment>
    { list }
    </React.Fragment>
    );

  2. Возвращает массив.

    return ([ list ]);