skip to Main Content

I’m using two useEffect in single component because there are two type of dependency. In first useEffect I’m updating a state but not able to get updated state in second useEffect console.

If I’m consoling it outside of useEffect then its working fine but I need in useEffect.

Note : Click on test button then check console.log there is getting initial state value instead of updated value.

import React, { useEffect, useState } from "react";
import "./styles.css";

export default function MyComponent() {
  const [editData, setEditData] = useState("initData");

  const depdency1 = "depdency1";
  const depdency2 = "depdency2";

  useEffect(() => {
    mufuction();
  }, [depdency1]);

  const mufuction = () => {
    setEditData("Updated Data");
  };

  useEffect(() => {
    console.log("editData", editData);
  }, [depdency2]);

  return <div className="App"></div>;
}

CodeSandbox

Thanks for your efforts!

3

Answers


  1. useEffect(() => {
        console.log("editData", editData);
    }, [depdency2]);
    

    The dependency2 value will not change, therefore you’ll only see the console.log with the value of the first render.

    If you want to trigger the second useEffect when editData is altered, set the dependancy array to contains editData:

    useEffect(() => {       
        mufuction();
    }, [ ]);                                // RUN ON MOUNT
    
    useEffect(() => {
        onsole.log("editData", editData);
    }, [editData]);                         // RUN WHEN editData changes
    

    Small runnable demo:

    const { useState, useEffect } = React;
    
    const Example = () => {
    
        const [editData, setEditData] = useState("initData");
    
        useEffect(() => {
          mufuction();
        }, [ ]);  // RUN ON MOUNT
    
        const mufuction = () => {
          setEditData("Updated Data");
        };
    
        useEffect(() => {
          console.log("editData", editData);
        }, [editData]); // RUN WHEN editData changes
    
        return <div className="App"></div>;
    }
    ReactDOM.render(<Example />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>
    editData initData
    editData Updated Data
    
    Login or Signup to reply.
  2. The second useEffect is not running when editData is updated because editData is not listed as one of its dependencies. The following code should work:

    import React, { useEffect, useState } from "react";
    import "./styles.css";
    
    export default function MyComponent() {
      const [editData, setEditData] = useState("initData");
    
      useEffect(() => {
        mufuction();
      }, []);
    
      const mufuction = () => {
        setEditData("Updated Data");
      };
    
      useEffect(() => {
        console.log("editData", editData);
      }, [editData]);
    
      return <div className="App"></div>;
    }
    
    Login or Signup to reply.
  3. Let’s redesign the layout of this component. You have a state. That state has an initial value. Let’s log the value of this state each time it is updated. Once when the component is created, and again when it is mounted.

    I included both a functional and class component version.

    Function component version

    const { useCallback, useEffect, useState } = React;
    
    const App = () => {
      const [data, setData] = useState("Initial Value");
    
      const updateDataState = useCallback(() => {
        setData("Updated Value"); // Mutate the data
      }, [data]);
    
      // componentDidMount
      useEffect(() => {
        updateDataState();
      }, []);
    
      // componentDidUpdate
      useEffect(() => {
        console.log("Data State:", data); // Log the value
      }, [data]);
    
      return (
        <div className="App">
          <h1>{data}</h1>
        </div>
      );
    }
    
    ReactDOM
      .createRoot(document.getElementById("root"))
      .render(<App />);
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

    Class component version

    const { Component } = React;
    
    class App extends Component {
      constructor(props) {
         super(props);
         this.state = { data: "Initial Value" };
         this.componentDidUpdate(); // Not needed, but force-logs initial state
      }
    
      updateDataState() {
        this.setState((state) => ({
          ...state,
          data: "Updated Value" // Mutate the data 
        }));
      }
    
      componentDidMount() {
        this.updateDataState();
      }
    
      componentDidUpdate() {
        console.log("Data State:", this.state.data); // Log the value
      }
    
      render() {
        return (
          <div className="App">
            <h1>{this.state.data}</h1>
          </div>
        );
      }
    }
    
    ReactDOM
      .createRoot(document.getElementById("root"))
      .render(<App />);
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search