1

My component uses the useEffect hook to watch for updates of a valve.

I have set a condition to prevent useEffect firing after mounting.

When the button is clicked, the value is updated from the initial state. Why does useEffect gets fired every time the button is clicked? The value is always the same so there's no update.

import React, { useState, useEffect } from "react"; function doSomething() { return [ { id: 1, prop1: "foo", prop2: "bar" }, ]; } export default function Choose() { const [tableData, setTableData] = useState([{}]) // runs after every render useEffect(()=> { if (Object.keys(tableData[0]).length > 0) { console.log("something changed") } }, [tableData]) return ( <div> <button type="button" onClick={(e)=> setTableData(doSomething())}>display</button> </div> ); } 
1
  • 1
    In the most simplistic terms: [] !== [] and {} !== {}. So every time doSomething is called, you indeed get a new value - even though all the properties are the same. Commented May 18, 2021 at 19:54

1 Answer 1

2

The doSomething function generates a new object, each time you click the button. Declare the array outside of the function, and return it inside it:

const arr = [ { id: 1, prop1: "foo", prop2: "bar" }, ] function doSomething() { return arr; } 

Example:

const { useState, useEffect } = React; const arr = [ { id: 1, prop1: "foo", prop2: "bar" }, ]; function doSomething() { return arr; } function Choose() { const [tableData, setTableData] = useState([{}]) useEffect(()=> { if (Object.keys(tableData[0]).length > 0) { console.log("something changed " + Math.random()); } }, [tableData]) return ( <div> <button type="button" onClick={(e)=> setTableData(doSomething())}>display</button> </div> ); } ReactDOM.render( <Choose />, root );
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <div id="root"></div>

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

2 Comments

what if the function returns sometimes the same value like for example using Math.random() how can I prevent react re rendering if the output value is the same as before ?
If the value is exactly the same (ie, the exact same object, the same number, etc...), useState would not cause a re-render.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.