0

I want to display the name based on user click. when browse button will click we will show list of name and if we click the name then i want to display the name with changing the state.

here is the sample code

const TestCli = () => {
  const [names, setfolderName] = React.useState([
    "sonu",
    "monu",
    "xyz",
    "abc",
    "lol",
  ]);
  const [isdiv, setisdiv] = React.useState(false);
  const [Name, setName] = React.useState("My name is:");
  const [isName, setisName] = React.useState(false);
  const displayFolder = () => {
    setisdiv(true);
  };
  const displayInfo = (name) => {
    setisdiv(!isdiv);
    setisName(true);
    setName("My nameis " + name);
    console.log(Name);
  };
  return (
    <React.Fragment>
      <div>My name is sonu</div>
      <button class="browseBtn" onClick={displayFolder}>
        Browse
      </button>
      {isdiv ? (
        <div>
          {names.map((name) => (
            <React.Fragment>
              <span onClick={() => displayInfo(name)}>{name}</span>
              <br></br>
            </React.Fragment>
          ))}
        </div>
      ) : null}
      {isName ? <div>{Name}</div> : null}
    </React.Fragment>
  );
};

ReactDOM.render(<TestCli />, document.getElementById("root"));
<div id="root" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

Here printing is successful but when I print on console, it is printing wrong. for example: when I first time clicks on any name then it is printing My name is: only. then when 2nd time clicks on any name whatever previously clicked that name is printing.

The state is not reflecting

Janez Kuhar
  • 3,705
  • 4
  • 22
  • 45
Rajendra Bar
  • 49
  • 1
  • 8
  • 1
    Please see answer here: https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately#:~:text=Think%20of%20setState()%20as,state%20changes%20are%20applied%20immediately. – Jacob Apr 20 '21 at 09:46
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – Janez Kuhar Apr 20 '21 at 10:36

2 Answers2

1

Usually, this can happen because setState is not an immediate command.

I checked your code, n here I just changed some unnecessary states you have done there. For example, you do not need state when you are not change anything, that can be a variable.. check the code :

  import React, { useState } from "react";

const TestCli = () => {
  const names = ["sonu", "monu", "xyz", "abc", "lol"];
  const [isdiv, setisdiv] = useState(false);

  const [Name, setName] = useState(null);

  return (
    <>
      <div>My name is sonu</div>
      <button class="browseBtn" onClick={() => setisdiv(true)}>
        Browse
      </button>
      {isdiv ? (
        <div>
          {names.map((name) => (
            <div key={name}>
              <span onClick={() => setName("My name is " + name)}>{name}</span>
              <br></br>
            </div>
          ))}
        </div>
      ) : null}

      {Name && <div>{Name}</div>}
    </>
  );
};

export default TestCli;

if something is unclear ask, kindly will help :D

PS.

Also, every list when you map through it should have a unique key. in this case i just putted your names as a unique key, but usually, you have an id. Keys help react to tell which item has been changed.. So this may cause some unexpected errors. Read more about keys here: https://reactjs.org/docs/lists-and-keys.html

Muhamet Smaili
  • 375
  • 2
  • 9
  • Can we use useEffect inside a function. if yes, How – Rajendra Bar Apr 20 '21 at 11:10
  • No, we can not use any hooks inside functions, setState is just a function that is setting the state and changing it. But hooks like useState, useCallbakcs, useEffect should be inside the body. – Muhamet Smaili Apr 20 '21 at 11:17
0

The reason it is happening is because , you are trying to print Name which is a state , but useState hook update setState is asynchronous so by the time it is trying to print the state of it , the value wouldn't have been updated , if you want to console the state , use useEffect passing parameter Name to see actual state

useEffect(()=>{
console.log(Name)},[Name])

For What you are trying to achieve , you can refer the below code


import React, { useState, useEffect } from "react";

const TestCli = () => {
  const names = ["sonu", "monu", "xyz", "abc", "lol"];
  const [isDiv, setIsDiv] = useState(false);
  const [Name, setName] = useState("My name is:" + names[0]);
  const [isName, setIsName] = useState(false);
  const displayFolder = () => {
    setIsDiv(true);
  };
  const displayInfo = (name) => {
    setIsDiv(!isDiv);
    setIsName(true);
    setName(`My name is ${name}`);
    //here you can make axios call
  };
  return (
    <>
      {isName ? <div>{Name}</div> : null}
      <button class="browseBtn" onClick={displayFolder}>
        Browse
      </button>
      {isDiv ? (
        <div>
          {names.map((name) => (
            <>
              <span onClick={() => displayInfo(name)} key={name}>
                {name}
              </span>
              <br></br>
            </>
          ))}
        </div>
      ) : null}
    </>
  );
};

export default TestCli;


You can refer this code sandbox for ref , the code is available at Test.js

Edit blissful-albattani-x0res

Goutham J.M
  • 1,726
  • 12
  • 25