Is it appropriate to use useEffect to fetch new state when a prop changes?

Quite simply, yes, this is an appropriate and correct usage of the useEffect hook. The useEffect hook is used to issue side-effects, e.g. fetching data from an external resource, and its dependency array is used to control when the side-effect may be triggered again during the life of the component, e.g. when a prop value changes. An example scenario is fetching a user's post by their id.

const Component = ({ userId }) => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch(`/api/posts/${userId}`)
      .then(response => response.json())
      .then(posts => setPosts(posts));
  }, [userId]);

  ...

You do need Effects to synchronize with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query.

What you might be getting tripped up on in the rest of the "you might not need an effect" section is that it's trying to point out some general React anti-patterns and correct pattern(s) to use.

A few examples:

  • "You don't need Effect to transform data for rendering"

    Just compute the transformed data directly and render. If it's "expensive" then use the useMemo hook to memoize the computed value.

  • "You don't need Effects to handle user events"

    Don't set some state that an event happened so an effect can be issued, just issue the effect from the event handler. Think of a form onSubmit handler.

  • Don't store props into local state and use a useEffect hook to synchronize the state to the prop value, just use the prop value directly.

For your specific code example this isn't an appropriate usage of the useEffect hook. The child component should just directly reference the currChildVal prop value and add 2 to it.

const Child = ({ parentVal }) => {
  return (
    <div style={{ border: "1px solid blue", margin: 30, padding: 10 }}>
      <span>childVal: {parentVal + 2}</span>
    </div>
  );
};
Answer from Drew Reese on Stack Overflow
Top answer
1 of 6
5

Is it appropriate to use useEffect to fetch new state when a prop changes?

Quite simply, yes, this is an appropriate and correct usage of the useEffect hook. The useEffect hook is used to issue side-effects, e.g. fetching data from an external resource, and its dependency array is used to control when the side-effect may be triggered again during the life of the component, e.g. when a prop value changes. An example scenario is fetching a user's post by their id.

const Component = ({ userId }) => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch(`/api/posts/${userId}`)
      .then(response => response.json())
      .then(posts => setPosts(posts));
  }, [userId]);

  ...

You do need Effects to synchronize with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query.

What you might be getting tripped up on in the rest of the "you might not need an effect" section is that it's trying to point out some general React anti-patterns and correct pattern(s) to use.

A few examples:

  • "You don't need Effect to transform data for rendering"

    Just compute the transformed data directly and render. If it's "expensive" then use the useMemo hook to memoize the computed value.

  • "You don't need Effects to handle user events"

    Don't set some state that an event happened so an effect can be issued, just issue the effect from the event handler. Think of a form onSubmit handler.

  • Don't store props into local state and use a useEffect hook to synchronize the state to the prop value, just use the prop value directly.

For your specific code example this isn't an appropriate usage of the useEffect hook. The child component should just directly reference the currChildVal prop value and add 2 to it.

const Child = ({ parentVal }) => {
  return (
    <div style={{ border: "1px solid blue", margin: 30, padding: 10 }}>
      <span>childVal: {parentVal + 2}</span>
    </div>
  );
};
2 of 6
2

It's mostly a question of the desired encapsulation of Child. If it is a reusable thing that should be agnostic of why parentVal changed, then yes it might be appropriate.

That tends to be the case if the component is going to be used in unknown situations, such as a lib, or something that's used a lot in your app to the point where you need the decoupling.

But if you do know about how that changes (button click) ahead of time, then yes arguably you can utilise that to remove the effects which would likely to lead to (pretty minor) perf improvements.

🌐
Medium
omarshishani.medium.com › why-useeffect-is-not-updating-when-props-change-c2e603a7e98b
Why useEffect is Not Updating When props Change 👻 | by Omar Shishani | Medium
January 9, 2021 - Why won’t my component register the changed values of props??? The answer for me was that I was not passing in props to useEffect as a dependency. It didn't even occur to me that it was useEffect which was causing the problem. In many cases, I use useEffect like componentDidMount. However, I only want it to run once, because I need to update state, and if useEffect runs on each state update it will cause an infinite loop.
Discussions

React Component UseEffect isn't rerendering upon prop change
In this component, I useEffect ... change, and reset the useEffect? In that if statement (counter === 0), I manually set it back using setCounter. however i dont know how to check for prop change. whenever last_time prop is updated. ... just on first look, you are setting ... More on stackoverflow.com
🌐 stackoverflow.com
February 15, 2022
useEffect is not executed when the prop changes
Typically assigning an object/array as a dependency in a useEffect is bad practice. You want something that will actually change (by value) since generally objects and arrays are passed by reference even if they change so I’m assuming react is seeing the children prop as the same reference and not triggering the useEffect More on reddit.com
🌐 r/reactjs
25
1
September 12, 2023
reactjs - useEffect isn't executed when prop changes - Stack Overflow
Example below passes the state setter to the SqlConnection class, so when the params are updated, the state change is triggered, the useEffect is now able to listen to the params change and now you are able to use them and set the sql connection with proper params. More on stackoverflow.com
🌐 stackoverflow.com
November 25, 2020
reactjs - react hooks props in useEffect - Stack Overflow
I have started using react-hooks and there is something I am trying to understand. I have this useEffect hook, I'm separating my useEffect hooks, I want to know when each hook runs. function MyComp( More on stackoverflow.com
🌐 stackoverflow.com
🌐
Today I Learned
til.hashrocket.com › posts › z1xzaupgpd-run-side-effect-when-a-prop-changes-whooks
Run side effect when a prop changes w/Hooks - Today I Learned
May 25, 2022 - If passing in this second argument, the effect function will only run when the values change. useEffect(() => console.log('value changed!'), [props.isOpen]); Now, you will see "value changed!" both on the first render and everytime isOpen changes.
🌐
React
react.dev › learn › you-might-not-need-an-effect
You Might Not Need an Effect – React
If your Effect also immediately updates the state, this restarts the whole process from scratch! To avoid the unnecessary render passes, transform all the data at the top level of your components. That code will automatically re-run whenever ...
🌐
Pluralsight
pluralsight.com › tech insights & how-to guides › tech guides & tutorials
Reacting to Prop Changes in a React Component | Pluralsight
May 2, 2025 - The way to do this in the hooks API is by using the effect hook. The effect hook can either run after every render, only on mount and unmount, or when specified values have been changed.
Find elsewhere
🌐
React
react.dev › reference › react › useEffect
useEffect – React
However, you can express that you ... to changes even though it is called from inside an Effect. Declare an Effect Event with the useEffectEvent Hook, and move the code reading shoppingCart inside of it: ... Effect Events are not reactive and must always be omitted from dependencies of your Effect. This is what lets you put non-reactive code (where you can read the latest value of some props and state) inside of them. By reading shoppingCart inside of onVisit, you ensure ...
🌐
Bobby Hadz
bobbyhadz.com › blog › react-update-state-when-props-change
Updating state when props change in React | bobbyhadz
Every time the parentCount prop changes, the useEffect hook is rerun and we use the setChildCount function to update the state. Add all of the props you want to track to the dependencies array of your useEffect hook.
Top answer
1 of 2
1

Update: Why you don't store connectionParams in a useState? This way you can pass them and rerender correctly.

const [connectionParams, setConnectionParams] = useState({});

return <SqlSchema connectionParams={connectionParams} setConnectionParams={setConnectionParams} />

You are creating a new connection of every render of the Parent sqlConnection={new SqlConnection()}. Try creating the connection on mount and then pass the variable to the child.

2 of 2
0

Passing the SqlConnection won't trigger component update when the connectionParams update within the class. You'd have to somehow subscribe to the connectionParams changes. Example below passes the state setter to the SqlConnection class, so when the params are updated, the state change is triggered, the useEffect is now able to listen to the params change and now you are able to use them and set the sql connection with proper params.

class SqlConnection {
  stateSetter;
  
  constructor(setter) {
    this.stateSetter = setter;
  }
  
  connectionParams = {};

  setConnection(params) {  
    this.connectionParams = params;
    this.stateSetter(this.connectionParams);
  }
}

const SqlSchema = () => {
  const [value, setValue] = React.useState({});
  const ref = React.useRef(null);
  
  React.useEffect(() => {
    ref.current = new SqlConnection(setValue);
  }, []);
  
  React.useEffect(() => {
     console.log('Current params - ', value); // do stuff with params
  }, [value]);

  const setParams = () => {
    ref.current.setConnection({ foo: 'bar' });
  };

  return <div>
    <button onClick={setParams}>Update params</button>
    {JSON.stringify(value)}
  </div>
}

ReactDOM.render(<SqlSchema />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

🌐
Codemzy
codemzy.com › blog › update-state-when-props-change-react
How to update state when props change in React components - Codemzy's Blog
August 14, 2023 - If you need to update your state when a prop changes, the easiest way to do this is React is with the `useEffect` hook. In this blog post, we will look at three options including `useEffect, the `key` prop, and removing state.
🌐
DEV Community
dev.to › mkamranhamid › using-useeffect-effectively-2722
using useEffect effectively - DEV Community
November 3, 2020 - function UserList({ apiUsers }) { const [loading, setLoading] = useState(true) const [users, setUsers] = useState(undefined) useEffect(() => { setUsers(apiUsers) setLoading(false) }, [apiUsers]) if (loading) return <Loader size="small" /> return ( <div className="container"> { users.map((user, index) => <UserCard key={index} data={user} />) } </div> ) } Here we are listening to the change in apiUsers prop so every time there's a change in it useEffect with its callback gets called
🌐
ReactHustle
reacthustle.com › blog › how-to-update-state-when-props-change-in-react
How to Update State when Props Change in React | ReactHustle
This is usually the cleaner approach ... the Navbar component using the key prop. We can use the useEffect hook to listen to changes to props and update our state this way....
🌐
GitHub
github.com › facebook › react › issues › 15523
useEffect for synchronizing state and props · Issue #15523 · facebook/react
April 29, 2019 - This one has been one of my biggest pain-points with stateful components in React (which is why I prefer stateless components with a state container, but those I widely demonized nowadays, so I am yet again trying to understand the idiomatic React way of doing this). The “old” ways were to sync in componentWillReceiveProps and later with getDerivedStateFromProps. Now I can do this with useEffect, where I specify props.item as the “dependency”, since I want to run it when the item changes.
Author   Yakimych
🌐
Reddit
reddit.com › r/reactjs › react component prop change not triggering useeffect() when inside another library
r/reactjs on Reddit: React component prop change not triggering useEffect() when inside another library
May 26, 2021 -

First off, I am painfully aware this is not an ideal scenario. I have an app using OpenUI5 with some React functional components/hooks inside:

private _myReactWindow = window["studioStepComponents"];
private _myReactView;
private someFunction(someNewValue) {
    this._myReactView.someProp = someNewValue
}
private someRenderFunction() {
    this._myReactView = this._myReactWindow.createElement(this._myReactWindow.MyReactComponent,
    {
        someProp: this.someValue
    });
} 

createElement is working fine and in "someFunction" I can see the correct values for this._myReactView.someProp, even after setting it to a different value, but the useEffect() hook is not triggering on the React side. Is there any way I can get it to pick up the change? I realize these are different frameworks with different bindings but with the value changing I still would have thought React would see the prop change.