React: нарушение инварианта: объекты недопустимы в качестве дочернего элемента React. - PullRequest
1 голос
/ 14 марта 2019

Я работаю над фильтром поиска ReactJS. В настоящее время я сталкиваюсь с проблемой, когда я вхожу в приложение ввода совпадений, и приложение выдает ошибку Objects are not valid as a React child (found: object with keys {id, companyName, account, venueCode, openDate, website, primaryPhone, emailAddress, description, firstName, lastName, active, title, department, officePhone, mobilePhone, tenantId, hidden, deleted, parentId}). If you meant to render a collection of children, use an array instead. Кто-нибудь, пожалуйста, помогите мне, как решить эту проблему. Я новичок и не очень разбираюсь в решении этой проблемы. Первый раз, когда приложение успешно рендерится, когда я ввожу некоторые совпадения, появляется ошибка.

Код

<code>        class Example extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      Item: 5,
      skip: 0
    }

    this.handleClick = this.handleClick.bind(this);
  }

  urlParams() {
    return `http://localhost:3001/meetups?filter[limit]=${(this.state.Item)}&&filter[skip]=${this.state.skip}`
  }

  handleClick() {
    this.setState({skip: this.state.skip + 1})
  }

  render() {
    return (
      <div>
        <a href={this.urlParams()}>Example link</a>
        <pre>{this.urlParams()}
) } } ReactDOM.render (, document.querySelector ('div # my-example'))

Ответы [ 4 ]

3 голосов
/ 14 марта 2019

Это происходит, когда вы пытаетесь визуализировать объект вместо JSX. Делая мое самое обоснованное предположение, я думаю, что эта строка является проблемой:

let filtered=this.state.data.filter((item)=>{
      return item.companyName.indexOf(keyword) > -1
    });

Фильтр представляется массивом объектов, а не JSX, поэтому в методе рендеринга:

{this.state.filtered.length === 0 ? dataRender : this.state.filtered}

потенциально пытается отобразить отфильтрованные объекты, а не JSX.

Чтобы исправить это, попробуйте добавить это:

const filterRender=this.state.filtered.map((dataItem)=>(
  <Table.Row key={dataItem.id}>
  <Table.Cell>{dataItem.companyName}</Table.Cell>
  <Table.Cell>{dataItem.primaryPhone}</Table.Cell>
  <Table.Cell>{dataItem.emailAddress}</Table.Cell>
  <Table.Cell>{dataItem.venueCode}</Table.Cell>
  <Table.Cell>{dataItem.account}</Table.Cell>
  <Table.Cell>{dataItem.openDate}</Table.Cell>
  <Table.Cell>{dataItem.website}</Table.Cell>
  <Table.Cell>{dataItem.description}</Table.Cell>
</Table.Row>
))

и изменив это на:

{this.state.filtered.length === 0 ? dataRender : filterRender}

Как указал @jsdeveloper ниже, было бы неплохо создать renderRow метод для этого.

2 голосов
/ 14 марта 2019

Единственное, что я бы добавил к ответу на сон, это то, что вы должны создать функцию для сопоставления с элементом данных:

getDataItems(data) {
    return data.map((dataItem)=>(
      <Table.Row key={dataItem.id}>
      <Table.Cell>{dataItem.companyName}</Table.Cell>
      <Table.Cell>{dataItem.primaryPhone}</Table.Cell>
      <Table.Cell>{dataItem.emailAddress}</Table.Cell>
      <Table.Cell>{dataItem.venueCode}</Table.Cell>
      <Table.Cell>{dataItem.account}</Table.Cell>
      <Table.Cell>{dataItem.openDate}</Table.Cell>
      <Table.Cell>{dataItem.website}</Table.Cell>
      <Table.Cell>{dataItem.description}</Table.Cell>
    </Table.Row>
    ))
}
render() {
  const filteredItems = getDataItems(this.state.filtered)
  const dataItems = getDataItems(this.state.data)
  ...
1 голос
/ 14 марта 2019

Я не могу проверить это, чтобы быть уверенным, но я ожидаю, что этот констант dataRender возвращает ряд строк без родительского элемента.Правильный способ сделать это - создать компонент <TableRow />, который использует функцию карты внутри функции рендеринга в вашем jsx, например:

...
<Table.Body>
    {this.state.filtered.length === 0 ? 
    this.state.data.map((dataItem)=>(<TableRow key={dataItem.id} item={dataItem}/>)
    : this.state.filtered}
</Table.Body>
...
1 голос
/ 14 марта 2019

Вы должны добавить опору состояния, которая обрабатывает, если Компонент готов к визуализации или вы должны визуализировать загрузчик.

Это решит проблему, если ваше имущество this.state.data уже заполнено вашим getDataMethod.

Итак, вы должны попытаться добавить начальное состояние proeprty, например:

class Organization extends Component {
  constructor(props){
    super(props);
    this.state={
      Item : 5,
      skip:0,
      isReady: false,
      data : [],
      filtered:[]
    }
    this.getData=this.getData.bind(this);
    this.btnClick=this.btnClick.bind(this);
    this.prevButton=this.prevButton.bind(this);
  }

и вы должны обрабатывать состояние isReady в вашем getData как:

 getData(){
    const {Item,skip}=this.state;
    axios.get(`http://localhost:8001/parties?filter[limit]=${Item}&&filter[skip]=${skip}`)
    .then(response=>{
      console.log(response.data);
      this.setState({
        isReady: true,
        data:response.data
      })
    })
  }

И добавьте условие в ваш render метод:

render() {
    if( !this.state.isReady ){
      return <div>Loading...</div>
    }
    // return your JSX
    return ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...