0

I'm stuck trying to understand why my state won't update until I change the value in the text input twice (calling the handleChange function). What am I doing wrong here?

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

export default function Typeahead(props){
    const {list}  = props;
    const [colorList] = useState(list.map(element => element.toLowerCase()));
    const [color,setColor] = useState();
    const [showResults, setShowResults]= useState(false);
    const [results,setResults]= useState();

    let handleChange = (e) =>{
        setShowResults(true);
        setColor(e.target.value.toLowerCase());
        const match = (colorList) =>{
            return colorList.startsWith(color,0);
        };
        const matches = colorList.filter(match);
        setResults((matches));

        console.log(results);
        console.log(showResults);
    };

    useEffect(() => {

        //setResults(list.map(elements => elements.toLowerCase()));
    }, [results]);

        return(
            <div>
                <input type= "text" onChange={handleChange}/>
                {showResults ?
                    <div>
                        {results.map((options) => {
                            return (
                                <option key={options} value={options}> {options}</option>
                            )
                        })}
                    </div>
                    : null }
            </div>
        );
}
Angela
  • 31
  • 8
  • If you are checking via console.log , then it may or may not show the change, since state updating is asynchronous in nature – Harmandeep Singh Kalsi Jul 14 '20 at 18:13
  • Setting state is asynchronous. your console.logs will always be one state change behind. –  Jul 14 '20 at 18:13
  • 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) –  Jul 14 '20 at 18:14
  • @ChrisG I understand that it will be one state change behind but I don't understand what to do to fix it. I've tried to use an initialize function + a useEfffect function but that didn't help – Angela Jul 14 '20 at 18:19
  • So besides the console.logs being behind, is there something else not working as expected? Because the state will change very soon after, which causes a re-render and your browser view should update accordingly. In case you're trying to run the commented out code, simply append that `map()` function to `colorList.filter(match)` –  Jul 14 '20 at 18:23
  • @ChrisG the commented out code is fine, I was using that to try to test if the useEffect was helping the state update or not. The only problem I have is that when I enter one letter into the input box, the results don't appear until I type two or more letters. Also when I delete character the results don't populate properly – Angela Jul 14 '20 at 18:32
  • 1
    Yes, I just saw that you're using `color` in the `match` function. That will use the previous value; simply replace with `color` with `e.target.value.toLowerCase()` –  Jul 14 '20 at 18:34
  • 1
    Fixed code: https://codesandbox.io/s/affectionate-violet-qnplw?file=/src/Typeahead.js –  Jul 14 '20 at 18:40
  • @ChrisG thank you so much :) I didn't realize that the setColor I was doing would render in the NEXT render – Angela Jul 14 '20 at 18:42
  • 1
    You're welcome, and I've just made several changes to the code sandbox –  Jul 14 '20 at 18:47
  • @ChrisG if I wanted to make the input text bold and the matching substring in the results bold as well would I need to make the changes in the return part or have an external function? – Angela Jul 14 '20 at 20:02
  • 1
    Mostly to the return part, see my codesandbox for an update –  Jul 14 '20 at 20:10
  • @ChrisG thank you for the comments as well, now I understand exactly what the useEffect function is used for! – Angela Jul 14 '20 at 20:14
  • No problem, I myself tend to stick to classes :) –  Jul 14 '20 at 20:19
  • @ChrisG I was wondering if you could help me out with this question because you seem to know everything related to the front end : https://stackoverflow.com/questions/63700330/how-to-find-the-sum-of-items-per-year-using-chart-js – Angela Sep 02 '20 at 07:08

0 Answers0