0

I'm trying to update my state by triggering the onClick event in my <Link>, but only after I click it twice then the output appears in my console, I have tried reading other question similar to this in stackoverflow but still could not find the solution, can anybody tell me what I did worng? Your help would be really great

import React,{useState} from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';

const [search, setSearch] = useState("");
const [keyword, setKeyword] = useState("");

const handleChange = (e) =>{
    setSearch(e.target.value);
    console.log(search);
};

const handleClick = () => {
    setKeyword(search);
    setSearch('');
    console.log(keyword);
};

return(
    <div>
        <input onChange={handleChange} value={search} placeholder="Search songs, artist, albums"/>

        <Link onClick = {handleClick} to={`/songlist/${keyword}`}>Search</Link>
    </div> 
)
  • Does this answer your question? [Why calling react setState method doesn't mutate the state immediately?](https://stackoverflow.com/questions/30782948/why-calling-react-setstate-method-doesnt-mutate-the-state-immediately) –  Jun 10 '20 at 07:57
  • so I need to pass a callback function in the setState for it to work immediately? – Muhd Iqbal Jun 10 '20 at 07:58
  • it gives me this error ** Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()**. – Muhd Iqbal Jun 10 '20 at 08:01
  • 1
    Exactly, you need to use `React.useEffect(() => { console.log(search); }, [search]);` (I'll also recommend to not use hooks as a react beginner) –  Jun 10 '20 at 08:01
  • because JS is async. you can use ```useEffect``` hook to handle effects. – Vahid Alimohamadi Jun 10 '20 at 08:03

3 Answers3

1

The thing you need to understand is : When you click, you add an event, and it's event is linked on your component and your props.

So you need to preventDefault to tell your event/props/component to act normally. Keep your actually code, but add e.preventDefault() at the begin of each event :)

Example :

const handleChange = (e) =>{
    e.preventDefault();
    setSearch(e.target.value);
    console.log(search);
};
RaeperFR
  • 27
  • 3
1

JS is async, so you need to handle effects using useEffect hook.

e.g. :

const [search, setSearch] = useState(null);
const [keyword, setKeyword] = useState(null);

const handleClick = () => {
  setKeyword(search);
  //setSearch('');
  //console.log(keyword);
};

React.useEffect(()=>{
  if (keyword) {
    console.log(keyword);
    setSearch(null);
  }
},[keyword]);
Vahid Alimohamadi
  • 4,900
  • 2
  • 22
  • 37
0

can you try this, change

<Link onClick = {handleClick} to={`/songlist/${keyword}`}>Search</Link>

to

<Link to={`/songlist/${search}`}>Search</Link>