0

I am not getting useState variable(selectedItem) updated value after updating it in useEffect. I have 2 useEffect first one dependency array is empty and i am changing dropdown value based on role.

In Second UseEffect Dependency array I have DropDown Value, there when i access DropDown Value, I am always getting Default value for my Dropdown. I am not able to understand why this is happening and how i can fix it. How to get selectedItem value based on role in other useEffect.

import { IDropdownOption } from '@fluentui/react';
import React from 'react';
import { useState } from 'react';

const [selectedItem, setSelecteditem] = useState<IDropdownOption>({
  key: "Default",
  text: "Default",
});

function MyFirstComponent(props: any)
{
 React.useEffect(() => {
    async function setDropDownValue() {
      if (props.userRole == "Admin") {
        setSelecteditem({
          key: "Admin",
          text: "Admin",
        });
      } else if (props.userRole == "Support") {
        setSelecteditem({
          key: "Support",
          text: "Support",
        });
      } else {
        setSelecteditem({
          key: "Default",
          text: "Default",
        });
      }
    }
    setDropDownValue();
  }, []);



 React.useEffect(() => {
   async function setDetailsBasedOnDropDownValue() {
     if (selectedItem?.key == "Admin")
     {
      //Business Logic
     } 
     else if (selectedItem?.key == "Support") 
     {
      //Business Logic
     } 
     else
      {
        //Business Logic
     }
   }
   setDetailsBasedOnDropDownValue();
 }, [selectedItem.key]);

}

1 Answers1

0

Since the setDetailsBasedOnDropDownValue depends on the selectedItem, you must re-create the function when the dependent value changes. Otherwise your function will always see the value of selectedItem when it was created.

Just Run code snippet below.

const { useState, useEffect, useCallback } = React;

const App = (props) => {
  const [selectedItem, setSelecteditem] = useState({
    key: "Default",
    text: "Default"
  });

  useEffect(() => {
    function setDropDownValue() {
      if (props.userRole === "Admin") {
        setSelecteditem({
          key: "Admin",
          text: "Admin"
        });
      } else if (props.userRole === "Support") {
        setSelecteditem({
          key: "Support",
          text: "Support"
        });
      } else {
        setSelecteditem({
          key: "Default",
          text: "Default"
        });
      }
    }
    setDropDownValue();
  }, []);
  
  const setDetailsBasedOnDropDownValue = useCallback(() => {
    function setDetailsBasedOnDropDownValue() {
      if (selectedItem.key === "Admin") {
        console.log("ADMIN Business Logic");
      } else if (selectedItem.key === "Support") {
        console.log("Support Business Logic");
      } else {
        console.log("Other Business Logic");
      }
    }
    setDetailsBasedOnDropDownValue();
  }, [selectedItem]);

  useEffect(setDetailsBasedOnDropDownValue, [selectedItem]);

  const setSelectedItem = (key, text = key) => {
     setSelecteditem({
          key,
          text
     });
  }

  return (
    <div class="container">
       <div class="row">
          <div class="col">
          <pre><code>
             {JSON.stringify(selectedItem, undefined, 2)}
          </code></pre>
          </div>
          <div class="col-8">
             <button type="button" class="btn btn-primary" onClick={() => setSelectedItem("Admin")}>Set Admin</button>
             <button type="button" class="btn btn-primary" onClick={() => setSelectedItem("Support")}>Set Support</button>
             <button type="button" class="btn btn-primary" onClick={() => setSelectedItem("Default")}>Set Default</button>
          </div>          
       </div>
       
    </div>
          
  );
};

ReactDOM.render(<App userRole="Admin" />, document.getElementById("root"));
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<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="root"></div>
René Link
  • 48,224
  • 13
  • 108
  • 140