Home > Blockchain >  Why click works only after two clicks using Reactjs
Why click works only after two clicks using Reactjs

Time:12-16

I know there's already a post about this issue but it does not seem like mine.

In my app I generate random Advice from API :

const Home = () => {
  const [advice, setAdvice] = useState({});

  const handleClick = async () => {
    try {
      const res = await fetch("https://api.adviceslip.com/advice");
      const data = await res.json();
      setAdvice((prevCount) => ({...prevCount, data.slip}) ); 
      console.log("my res", advice.advice)
    } catch (err) {
      console.log(err);
    }
  }
  useEffect(() => {
    handleClick();
  }, []);
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Advice generator app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
    
       <Box handleClick={handleClick} advice={advice.advice} key={advice.id} /> 
    </div>
  )
}

The click event is in another component :

 const Box = ( { handleClick, advice }) => {
      return (
          <button className='ag-advice__btn' onClick={handleClick}></button>
      )
  }

The first time, the advice is shown, I need to click 2 times to show the next advice.

CodePudding user response:

that's because in advise component has not rerendered yet, so advice is empty and in second click advice has previous value so it will log previous one

if you want to see exact value of it before rerendering you can see that in setAdvise funtion as pevState otherwise you can have useEffect for it to see what that is after rerendering

first solution:

  const handleClick = async () => {
    try {
      const res = await fetch("https://api.adviceslip.com/advice");
      const data = await res.json();
      setAdvice((prevCount) => ({...prevCount, data.slip}) ); 
      // to just see what is inside of advice state before rerendering
      setAdvice((prevCount) => {
         console.log("my res", prevCount?.advice)
       } ); 
     
    } catch (err) {
      console.log(err);
    }
  }

second solution :

const Home = () => {
  const [advice, setAdvice] = useState({});

  const handleClick = async () => {
    try {
      const res = await fetch("https://api.adviceslip.com/advice");
      const data = await res.json();
      setAdvice((prevCount) => ({...prevCount, data.slip}) ); 
     
    } catch (err) {
      console.log(err);
    }
  }

  useEffect(()=>{
       console.log('advice value: ',advice)
     },[advice])
   
  useEffect(() => {
    handleClick();
  }, []);
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Advice generator app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
    
       <Box handleClick={handleClick} advice={advice.advice} key={advice.id} /> 
    </div>
  )
}

CodePudding user response:

Well, this was not the answer i was expecting, i don't know why and it's not practical, but i just had to wait a second or two before clicking again !! it's not convenient at all !

if anyone have any ideas how to improve this !

  • Related