3
votes

React: violation invariante: les objets ne sont pas valides en tant qu'enfant React

Je travaille sur le filtre de recherche ReactJS, actuellement je suis confronté à un problème lorsque j'entre l'application d'entrée de correspondance est plantée et donne cette erreur Les objets ne sont pas valides en tant qu'enfant React (trouvé: objet avec les clés {id, companyName , compte, venueCode, openDate, site Web, primaryPhone, emailAddress, description, firstName, lastName, actif, titre, département, officePhone, mobilePhone, tenantId, masqué, supprimé, parentId}). Si vous vouliez rendre une collection d'enfants, utilisez plutôt un tableau. Quelqu'un, s'il vous plaît, aidez-moi à résoudre ce problème. Je suis débutant et n'ai pas beaucoup de connaissances pour résoudre ce problème. La première fois que l'application est affichée avec succès lorsque j'entre une entrée de correspondance, cela me donne une erreur.

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()}</pre>
        <button onClick={this.handleClick}>Change link</button>
      </div>
    )
  }
}


ReactDOM.render(<Example/>, document.querySelector('div#my-example' ))


0 commentaires

5 Réponses :


7
votes

Cela se produit lorsque vous essayez de rendre un objet au lieu de JSX. En faisant ma meilleure supposition, je pense que cette ligne est le problème:

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

Filtered semble être un tableau d'objets, pas JSX, donc dans la méthode de rendu:

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>
))

essaie potentiellement de rendre des objets filtrés, pas JSX.

Pour résoudre ce problème, essayez d'ajouter ceci:

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

et changer ceci en:

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

Comme @jsdeveloper l'a souligné ci-dessous, ce serait une bonne idée de créer une méthode renderRow pour gérer cela .


6 commentaires

J'ai encore une question, pourriez-vous s'il vous plaît?


@Jon quelle est votre question?


En fait, je souhaite accepter les entrées en minuscules ou en majuscules ou en majuscules. Comment puis-je faire ceci .? Veuillez aider


@Jon change la requête de recherche en minuscules et l'élément à comparer en minuscules: let keyword = event.target.value.toLowerCase (); let filtered = this.state.data.filter ((item) => {return item.companyName.toLowerCase (). indexOf (keyword)> -1});


Merci pour votre message . En fait, j'ai un problème avec le bouton suivant si je recherche quelque chose dans la zone de recherche et que je clique sur le bouton suivant, cela me donne un tableau dans la console. il ne met pas à jour l'interface utilisateur le suivant.


Aidez-moi à répondre à cette question stackoverflow.com/questions/55166774/…



1
votes

Vous devez ajouter un accessoire d'état qui gère si le composant est prêt à être rendu ou si vous devez rendre un chargeur.

Cela résoudra le problème si votre propriété this.state.data est déjà renseigné par votre getDataMethod.

Vous devriez donc essayer d'ajouter une propriété d'état initial comme:

render() {
    if( !this.state.isReady ){
      return <div>Loading...</div>
    }
    // return your JSX
    return ....
}

et vous devriez gérez l'état isReady dans votre getData comme:

 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
      })
    })
  }

Et ajoutez une condition dans votre méthode render : p >

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);
  }


1 commentaires

Aidez-moi à répondre à cette question stackoverflow.com/questions/55166774/…



1
votes

Je ne peux pas tester cela pour en être certain mais je m'attends à ce que dataRender const renvoie une série de lignes sans parent contenant. La bonne façon de procéder serait de créer un composant qui utilise la fonction de carte à l'intérieur de la fonction de rendu dans votre jsx comme ceci:

...
<Table.Body>
    {this.state.filtered.length === 0 ? 
    this.state.data.map((dataItem)=>(<TableRow key={dataItem.id} item={dataItem}/>)
    : this.state.filtered}
</Table.Body>
...


1 commentaires

Aidez-moi à répondre à cette question stackoverflow.com/questions/55166774/…



3
votes

La seule chose que j'ajouterais à la réponse endormie serait que vous devriez créer une fonction pour mapper à un dataitem:

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 commentaires

Aidez-moi à répondre à cette question stackoverflow.com/questions/55166774/…



0
votes

J'ai eu ce problème et c'était une solution vraiment simple. J'avais un objet imbriqué dans un objet, puis j'ai essayé d'afficher cet objet dans JSX, plutôt qu'une propriété de cet objet. Cette erreur s'affichait à la ligne où cet objet était défini sur l'état, et non là où l'objet a été appelé à partir de l'état dans JSX.

Objet dans l'état:

<div>{this.state.test.status.text}</div>

JSX (faux)

<div>{this.state.test.status}</div>

JSX (droit)

    test: { status: { id: 1, text: "value" } }


0 commentaires