0
votes

I am passing state as a variable down to a component via props like to...

const [someState, setSomeState] = useState([])
PlaceDataInIndexDB({ setSomeState: setSomeState,
    user: props.user })

And in the PlaceDataInIndexDB.js I have a useEffect which eventually sets the state using

useEffect(() => {
    props.setSomeState([array])
}), [props.user]
 

The issue is that I get a warning saying I need to use props in my dependency array, however, I do not want the useEffect to run every time props change because I have a lot of other props in there. What can I do for this? This is an extremely simplified version of my code. i can post exact code but it is a lot more to look through.

And here is the warning...

React Hook useEffect has a missing dependency: 'props'. Either include it or remove the dependency array. However, 'props' will change when any prop changes, so the preferred fix is to destructure the 'props' object outside of the useEffect call and refer to those specific props inside useEffect react-hooks/exhaustive-deps

1
Yes but how can I do this with state? I know how to do it with a variable. - Justin Oberle
Do what it tells you to. Destructure the props before accessing them in useEffect(()=>{ setSomeState()},[user]) - Vinnie James
can you please show how to do this with setSomeState? - Justin Oberle
Anyone? I am not sure how to destructure state. Obviously other props can be initialized as const something = props.something but how to do this with a setState function? - Justin Oberle
const {user, setSomeState} = props; useEffect(()=>{setSomeState()}, [user]); I tried this as mentioned above but it still wants me to put setSomeState in the dependency array. I have been told to this is bad form. - Justin Oberle

1 Answers

1
votes

It's telling you what the issue is. Generally, anything referenced inside of the useEffect function needs to also exist in the dependency array, so React knows to run it again when those things change. If the thing you're using is a property of some other object (like props), it's best to pull the values out of there prior to referencing them.

const PlaceDataInIndexDB = (props) => {
  const { setSomeState, user } = props

  useEffect(() => {
    setSomeState([array])
  }), [setSomeState, array] // <-- your example doesn't show where `array` comes from, but needed here as well

  // ...
}

You can, in fact, destructure the props inline so that you never even have a reference to the entire props object:

const PlaceDataInIndexDB = ({ setSomeState, user }) => {

Note that setSomeState must also be in the dependency array. If -- and only if -- the useState is in the same component, the linter is smart enough to know that it never changes and lets you leave it out. However, if it's passed in as a prop from somewhere else, there is no way for it to know.

The linting rules for hooks are very good. By and large, unless you really know what you're doing, you can blindly follow the suggestions it makes. Eslint actually added an entire "suggestions" feature for this specific rule, which e.g. vscode will change for you if you put your cursor on the error and press ctrl+.