Renato Maretić
Renato Maretić

Reputation: 355

ReactJS: Component doesn't rerender on state change

I am trying to update state on click event using react hooks. State changes, but component doesn't rerender. Here is my code snippet:

function ThirdPage() {
const [selectedIngredients, setSelectedIngredients] = useState([])

const DeleteIngredient = (ingredient) => {
    let selectedIngredientsContainer = selectedIngredients;
    selectedIngredientsContainer.splice(selectedIngredientsContainer.indexOf(ingredient), 1);
    setSelectedIngredients(selectedIngredientsContainer);
    console.log(selectedIngredients);
}


const selectedIngredientsDiv = selectedIngredients.map(ingredient =>
    (
    <div className={styles.selectedIngredientsDiv}>{ingredient}
                                                    <div className={styles.DeleteIngredient}
                                                        onClick={() => {
                                                        DeleteIngredient(ingredient)}}>x</div></div>
    ))

return (
...

What am I doing wrong? Thanks in advance!

Upvotes: 0

Views: 111

Answers (3)

Tinu Jos K
Tinu Jos K

Reputation: 920

The answer is very Simple, your state array selectedIngredients is initialized with an empty array, so when you call map on the empty array, it will not even run once and thus DeleteIngredient is never called and your state does not change, thus no re-render happens

Upvotes: 0

Pradeepb
Pradeepb

Reputation: 2562

Issue with you splice as its not being saved to selectedIngredientsContainer. I would do following:

selectedIngredientsContainer = selectedIngredientsContainer.filter(value => value !== ingredient);

or

selectedIngredientsContainer.splice(selectedIngredientsContainer.indexOf(ingredient), 1 );
setSelectedIngredients([...selectedIngredientsContainer]);

Hope it helps.

Upvotes: 2

Michael Cacciano
Michael Cacciano

Reputation: 389

normally I would leave an explanation on what's going on but tldr is that you should check first to make sure that you're array isn't empty, then you you can filter out the currentIngredients. Also you don't need curly brackets to call that function in the jsx but that can be personal flavor for personal code. I apologize if this doesn't help but I have to head out to work. Good luck!

function ThirdPage() {
  const [selectedIngredients, setSelectedIngredients] = useState([]);

  const DeleteIngredient = ingredient => {
    // let selectedIngredientsContainer = selectedIngredients;
    // selectedIngredientsContainer.splice(selectedIngredientsContainer.indexOf(ingredient), 1);
    // setSelectedIngredients(selectedIngredientsContainer);
    // console.log(selectedIngredients);
    if (selectedIngredients.length > 0) {
      // this assumes that there is an id property but you could compare whatever you want in the Array.filter() methods
      const filteredIngredients = setSelectedIngredients.filter(selectedIngredient => selectedIngredient.id !== ingredient.id);
      setSelectedIngredients(filteredIngredients);
    }
    // nothing in ingredients - default logic so whatever you want
    // log something for your sanity so you know the array is empty
    return;
  };

  const selectedIngredientsDiv = selectedIngredients.map(ingredient => (
    <div className={styles.selectedIngredientsDiv}>
      {ingredient}
      <div className={styles.DeleteIngredient} onClick={() => DeleteIngredient(ingredient)}>
        x
      </div>
    </div>
  ));
}

Upvotes: 0

Related Questions