1

Hi i'm new to react js and i was wondering why my component is rendering twice(useeffect runs twice). I tried removing strict mode and it renders only once but even then i don't understand why count is shown as 01 instead of just only 1. if i add the event handler the component breaks and i get that newarray[id][1]-1 is undefined (the function runs even if i don't click - or +)

import React, { useEffect, useState } from "react"; import { useOutletContext } from "react-router-dom"; function ShoppingCart(prop) { const [productstobuy, setProducts] = useState([]); const [count, setCount] = useState([0]) console.log(productstobuy) /* const handlePlusMinus = (sign,id) => { console.log("i'm in") const newarray = [...productstobuy] console.log(newarray) if (sign === "+") { newarray[id][1] = newarray[id][1]+1 } else if ((newarray[id][1]-1) >= 1) { newarray[id][1] = newarray[id][1]+1 } setProducts(newarray); } */ const allItems = useOutletContext() useEffect(() => { setCount(count + 1) console.log("called") let toadd = allItems.filter((elem, index) => { return index === prop.index }) console.log(toadd); let productexsist = productstobuy.filter((elem) => { return elem[0] === toadd }) console.log(productexsist.length) if (!productexsist.length) { console.log([(allItems.filter((elem, index) => { return index === prop.index }))[0], 1]) setProducts(oldArray => [...oldArray, [toadd[0], 1]]); console.log(productstobuy) } else { console.log("wrong") } }, [prop.index]) return ( <div> {count} {console.log(productstobuy)} {productstobuy.length > 0 ? productstobuy.map((product) => { console.log(product[1]) return (<div className="product" id={prop.index}>{product[0]}<div><button id={prop.index} /*onClick={handlePlusMinus("-",prop.index)}*/>-</button><input type="number" value={product[1]} /><button id={prop.index} /*onClick={handlePlusMinus("-",prop.index)}*/>+</button></div></div>) }) : null} </div> ); } export { ShoppingCart } 
3
  • 1
    Is your question why your component renders twice or why you're getting 01? It seems like you already know that it's rendering twice due to strict mode. It looks like your question is mainly only about the 01 issue you're facing and isn't related to thee rendering twice behaviour. The 01 occurs because your state is initially an array [0], which you're adding with 1, that produces "01". Commented Aug 28, 2022 at 13:38
  • Yes i was wondering about the 01 issue and also why the component runs handlePlusMinus before rendering the component Commented Aug 28, 2022 at 13:47
  • 1
    The useEffect running twice is a default behaviour in StrictMode now. stackoverflow.com/questions/72238175/… Commented Aug 28, 2022 at 14:07

3 Answers 3

2

why count is shown as 01 instead of just only 1

It's because of this line const [count, setCount] = useState([0]). count should be initialised as a number instead of an array. What actually happened in the useEffect was setCount([0]+1) instead of the intended setCount(0+1)

the function runs even if i don't click - or +

Instead of putting onClick={handlePlusMinus("-",prop.index)}, try onClick={() => handlePlusMinus("-",prop.index)}instead. this would ensure that the handlePlusMinus function is only called when the element is clicked. Elaboration here: React onClick function fires on render

Sign up to request clarification or add additional context in comments.

Comments

1

It renders twice because of the Strict Mode.
https://reactjs.org/docs/strict-mode.html

Comments

1

I am assuming you are using react 18 latest. so in develop mode it executes useEffect twice.

You can just remove <Strict> </Strict>

In App.js it should work as expected

Keep in mind Strict component gives a lot of useful warnings.

1 Comment

exactly been wondering about it for hours, thanks mate!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.