skip to Main Content

I am trying to write a component that lists a set of results when clicking the Find button. However when I click the Find button, the results state variable is not being reset when I call setResults([]).

Also it does not return each result in the results array, only the latest one. Could I be calling results.map or result.resultItems.map incorrectly as well?

This is what I look like when I click the Find button three times:

State not being reset, and only returns latest result

I need it to look like this, even when clicking the Find button again:

Correct outcome

  const SearchContact = () => {
    const [results, setResults] = useState([]);

    const handleFind = () => {
      setResults([]);

      const response = [
        { name: "Tim", email: "[email protected]" },
        { name: "Fred", email: "[email protected]" }
      ];

      for (var i = 0; i < response.length; i++) {
        const resultItems = [];

        resultItems.push(<div>{response[i].name}</div>);
        resultItems.push(<div>{response[i].email}</div>);

        setResults([...results, { resultItems: resultItems }]);
      }
    }

    return (
      <Button onClick={handleFind}>Find</Button>
        {results.map((result, index) => {
          return (
            <div key={index}>
              {result.resultItems.map((resultItem, index) => {
                return <div key={index}>{resultItem}</div>;
              })}
            </div>
          );
      })}
    )
}

2

Answers


  1. Try tihs:

     const SearchContact = () => {
      const [results, setResults] = useState([]);
    
      const handleFind = () => {
        const response = [
          { name: "Tim", email: "[email protected]" },
          { name: "Fred", email: "[email protected]" }
        ];
    
        const newResults = response.map((item) => {
          const resultItems = [
            <div key="name">{item.name}</div>,
            <div key="email">{item.email}</div>
          ];
    
          return { resultItems };
        });
    
        setResults(newResults);
      };
    
      return (
        <div>
          <Button onClick={handleFind}>Find</Button>
          {results.map((result, index) => (
            <div key={index}>
              {result.resultItems.map((resultItem, idx) => (
                <div key={idx}>{resultItem}</div>
              ))}
            </div>
          ))}
        </div>
      );
    };
    
    Login or Signup to reply.
  2. Simply call setResults(results) in the handleFind function, no need to call setResults([]), or any of the looping logic, like this:

        const handleFind = () => {
    
          // probably change to an API call in future
          const response = [
            { name: "Tim", email: "[email protected]" },
            { name: "Fred", email: "[email protected]" }
          ];
          setResults(response);
          }
        }
    

    and the in the JSX do:

     {results.map((result, index) => {
              return (
                <div key={index}>
                  <div>{result.name}</div>
                  <div>{result.email}</div>
                </div>
              );
          })}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search