0

I want to update State variable on react, when i set it by default my map function work well. But now when i update my state variable with setState i have the response map is not a function here is my code.

import React from 'react';

class Corps extends React.Component{

    state = {
      annonces : [
        {
          nom : " Karim Ngami",
          annonces: " selon le CEO de google Mr Karim Ngami google lens prends une nouvelle tournure"
        },
        {
          nom : " Brigitte Bami",
          annonces: "Je n'ai jamais douté de mon fils, je savais qu'il sera un grand home"
        },
        {
          nom : "Gladice Ngami",
          annonces: "Le monde est étonné par ces proesses, mais nous non (rire) il savait clairement ou il allait"
        },

      ]
    }

    addAnonces = () =>{

      this.setState({
        annonces : this.state.annonces.push({
          nom : "Nkodi Ngami",
          annonces: "Le monde est étonné par ces proesses, mais nous non (rire) il savait clairement ou il allait"
        })
      })

      console.log(this.state.annonces.length);
    }

    render(){



      return(<div>
                <h5>Mes annonces</h5>
                <div className ="row">

                   <div className="col-sm-10 col-sm-push-1">
                        listes

                      {this.state.annonces.map((item) =>(
            <div className ="row"> 
              <div className="col-sm-4">
                <span>{item.nom} :</span>

              </div>
              <div className="col-sm-7 col-sm-push-1">
                <span>{item.annonces}</span>
              </div>
            </div>) 
            )}
                  <button className="btn-success" onClick={this.addAnonces}> Envoyé </button>
                   </div>
                   <div className="col-sm-10 col-sm-push-1">
                        <form>
                            <label for="nom">Votre nom:</label> <input type="text" id="nom" /><br/>
                            <label for="texte">votre annonce:</label><textarea placeholder="Ecrivez votre annonce" name="texte" id="texte">
                            </textarea><br/>

                        </form>
                   </div>
                </div> 
             </div>
            );  
    }
}

export default Corps; 
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129

6 Answers6

1

The trouble is that .map is a method which can only be called on an array. When you are calling setState in your case you are actually setting annonces to be the return of array.push which I am pretty sure is the length of the array, which is a number. A number is of course not an array which is why you no longer can call .map.

What you want to do is set announces to be a new array that contains the new value and the old values. You can use the spread operator for this and your code would look something like this.

const stateCopy = [...this.state.annonces];
stateCopy.push({
    nom : "Nkodi Ngami",
    annonces: "Le monde est étonné par ces proesses, mais nous non (rire) il savait clairement ou il allait"
})

this.setState({annonces: stateCopy});

Of course this is a verbose way of doing this, but it should highlight 2 things.

1)You are now not setting announces to a number, but rather an array

2)You are not mutating the array, but rather creating a copy of the original and passing the new one to setState

Chaim Friedman
  • 6,124
  • 4
  • 33
  • 61
1

You shouldn't try to modify react state directly. You can try something like this:


  addAnonces = () => {
    // make a copy of this.state.annonces
    const newAnnonces = [...this.state.annonces];
    newAnnonces.push({
      nom: 'Nkodi Ngami',
      annonces: 'Le monde est étonné par ces proesses, mais nous non (rire) il savait clairement ou il allait',
    });
    this.setState({
      annonces: newAnnonces,
    });

    console.log(this.state.annonces.length);
  }

Loc Mai
  • 217
  • 3
  • 9
1

You can just use the spread operator instead of trying to mutate your state array with annonces.push()

addAnonces = () => {
    this.setState({
      annonces: [...this.state.annonces, {
        nom: 'Nkodi Ngami',
        annonces:
          'Le monde est étonné par ces proesses, mais nous non (rire) il savait clairement ou il allait',
      }]
    });
  };
111
Duderino9000
  • 2,535
  • 4
  • 31
  • 37
1

Use spread operator (...)

this.setState({ 
annonces: [...this.state.annonces, { nom : "Nkodi Ngami", annonces: "Je n'ai jamais douté de mon fils, je savais qu'il sera un grand home" }}]
})
suicide11
  • 57
  • 1
1

One thing you should definitely avoid in React is to mutate the state itself, push will modify the array in the state. You may try to use spread operator instead.

addAnonces = () => {
    this.setState(previousState => ({
        annonces: [
            ...previousState.annonces,
            {
                nom : "Nkodi Ngami",
                annonces: "Le monde est étonné par ces proesses, mais nous non (rire) il savait clairement ou il allait"
            },
        ],
    }), () => {
        console.log(this.state.annonces.length);
    });
}

And if you want to check the length of the annonces, you should put it in setState callback as setState happening in async

Ewe Tek Min
  • 855
  • 10
  • 19
1

Problem lays on your addAnnonces method

this.state.annonces.push({ nom: "nom4", annonces: "annonce4" }) will add a row in your announces array but react will not take it as state change and it will not effect on UI too. React will only know the state change by setState(...)

Another stuff is though your are try to assign using this.setState(...) but this.state.annonces.push(...) will return length of array not the array itself

So by this following code you actually assign the length of array to the state change and react get it as integer rather array and hence your .map fall into a trouble

addAnonces = () =>{
   this.setState({
       annonces : this.state.annonces.push({...})

If you really want to do the change in a single line of your array you may try following code

addAnnonces = () => {
    this.setState({
      annonces: [...this.state.annonces, { nom: "nom4", annonces: "annonce4" }]
    });
  };

Hope you got the idea

tareq aziz
  • 749
  • 4
  • 11