0

I'm somewhat new to react, and I'm trying to learn when every time a component will re-render. Usually I'm good at figuring this stuff out on my own, but I can't seem to find the logic in these

Exhibit A

const Science = () => {
    console.log('Rendering')

    useEffect(() => console.log('Effect ran'))

    console.log('Returning')

    return <div></div>
}

This outputs

Rendering
Returning
Rendering
Returning
Effect ran

I don't understand why it re-renders, and why the useEffect code comes after both renders and returns.

Exhibit B

const Science = () => {
    console.log('Rendering')

    useEffect(() => console.log('First effect ran'))
    useEffect(() => console.log('Second effect ran'))

    console.log('Returning')

    return <div></div>
}

This outputs

Rendering
Returning
Rendering
Returning
First effect ran
Second effect ran

My guess to why it re-renders in Exhibit A was that useEffect causes a re-render, but seen here, only one useEffect will cause a re-render. Unsure of this behavior.

Exhibit C

const Science = () => {
    console.log('Rendering')

    let numRenders = useRef(0)
    console.log(++numRenders.current)

    console.log('Returning')

    return <div></div>
}

This one really confuses me, as it outputs

Rendering
1
Returning
Rendering
1
Returning

I don't understand why on the second render, it doesn't increment. I know that it does permanently increment the value, and not just for the logging.

Thanks.

ZeroSevenTen
  • 1,122
  • 2
  • 9
  • 20

2 Answers2

1

At first, your jsx is rendered. Then lifecycle hooks executed and the component is rerendered. then each time that any state changes the component is rendered or props are changed.

Your useEffect code doesn't have any dependencies but you did not mention it. This way is correct in this case

useEffect(() => console.log("useEffect was ran") , [])
S. Hesam
  • 5,266
  • 3
  • 37
  • 59
1

useEffect callback executed asynchronously after the render phase, that's exactly A and B.

As for Exhibit C, it outputs:

Rendering 
1
Returning 

And not rendered twice, it renders twice because of other reasons (like a render of a parent which you not showing us). Anyways, useRef doesn't trigger render so due to closures updating the reference is pointless (it will always show the first value rendered).

In other words, as it's function component, render triggers the function and the updated value will be valuated.

See codesandbox attached.

Edit priceless-silence-r3x4r

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • That could be true, there is a parent component (App.tsx), so maybe it is causing the re-render. Thanks. – ZeroSevenTen Apr 23 '20 at 20:14
  • I tried to answer all your questions, see related question it may help either: https://stackoverflow.com/questions/59841800/react-useeffect-in-depth-use-of-useeffect/59841947#59841947 – Dennis Vash Apr 23 '20 at 20:18