skip to Main Content

everyone!
I have this code:

const [searchOption, setSearchOption] = useState('');

function clearSearchField (){
        setSearchOption("");
        sendQuery();
}

function sendQuery() {
        fetch(`${url}/?search=${searchOption}`,{
            method:'GET'})
        .then(response => response.json())
        .then(
            (result) => {
                setIsLoaded(true)
                setError(false)
                setUsersList(result)
            },
            (error) => {
                setIsLoaded(true)
                setError(error)
            }
        )
    }
<Button variant="outline-secondary" size="lg" className='input-group-text' onClick={sendQuery}>search</Button>
<Button variant="outline-secondary" size="lg" className='input-group-text me-5' onClick={clearSearchField}>X</Button>

state searchOption doesn’t update when raise sendQuery() function in clearSearchField.
I know that is because of asynchrony.

How to make it work properly? Please help me

I know that in class-component we can use this way:

this.setState({
            searchOption: ""
          }, () => ( this.sendQuery() ));

In function-component we can use useEffect hook:

useEffect(() => {
        sendQuery();
    }, [searchOption])

but it will send query every time when searchOption changes. But I need it clears searchOption and sends query only when user clicks on X-button

3

Answers


  1. Why don’t you put some logic inside useEffect that determines the execution based on the state value of searchOption?

    like

    useEffect(() => {
        if(searchOption.length > 0) sendQuery();
        }, [searchOption])
    
    Login or Signup to reply.
  2. I think the below code will fix your problem but I don’t know if it is the most optimal way to solve this problem. Also, I haven’t tested it but I think this should work.

    function Component() {
    const [searchOption, setSearchOption] = useState('');
    
    function clearSearchField (){
            const newSearchOption = "";
            setSearchOption(newSearchOption);
            sendQuery(newSearchOption); 
    }
    
    // send query takes a string parameter now
    function sendQuery(searchOptionString) {
        fetch(`${url}/?search=${searchOptionString}`,{
            method:'GET'})
        .then(response => response.json())
        .then(
            (result) => {
                setIsLoaded(true)
                setError(false)
                setUsersList(result)
            },
            (error) => {
                setIsLoaded(true)
                setError(error)
            }
        )
    }
    
    return (
        <>
            <Button 
                variant="outline-secondary" 
                size="lg" 
                className='input-group-text' 
                onClick={() => sendQuery(searchOption)}
            >
                search
            </Button>
            <Button 
                variant="outline-secondary" 
                size="lg" 
                className='input-group-text me-5' 
                onClick={clearSearchField}
            >
                X
            </Button>
        </>
    );
    

    }

    Login or Signup to reply.
  3. I think you should accept searchOption as an argument for the sendQuery method, like this

    function sendQuery(searchOption) {
        fetch(`${url}/?search=${searchOption}`,{
            method:'GET'})
        .then(response => response.json())
        .then(
            (result) => {
                setIsLoaded(true)
                setError(false)
                setUsersList(result)
            },
            (error) => {
                setIsLoaded(true)
                setError(error)
            }
        )
    }
    

    Also if you don’t want the sendQuery function to be called again and again whenever the searchOption changes I’d suggest that you don’t pass the searchOption in useEffect’s parameter. In that way the sendQuery function will only trigger once when the component is mounted and then you can normally run sendQuery only on click of X button or search button.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search