Search code examples
javascriptreactjsreact-hooksfetchuse-state

Retrieving value from onChange option dropdown with useState and fetch request


I'm building a filter to show a list of values based on the option selected. The data is populated by a fetch request, which is then mapped over to show the values.

This part is all working. However I am finding that the drop down doesn't seem to be registering the onChange event and therefor not updating the value from null.

Here is my code...

import ProductCard from "../ProductCard";
import "./style.css";

function ProductFilter(props) {
const [designerData, setDesignerData] = useState([]);
const [selectedDesigner, setSelectedDesigner] = useState(null);

  useEffect(() => {
    fetch("/uk/plpslice/listing-api/query?setId=9645&view=180&gender=Men")
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        setDesignerData(data.listing.products);
      });
  }, []);

  return (
    <div className="ProductFilter">
      <select>
      {designerData.map((designer, id) => {
        return (
          <option
            value={[designer.brand.name]}
            onChange={e => {
              console.log('this is on change', e);
              setSelectedDesigner(e.target.value)}}
          >
            {[designer.brand.name]}
          </option>
        );
      })}
      </select>
      <h1>{console.log('this is the selected designer',selectedDesigner)}</h1>
    </div>
  );
}

export default ProductFilter;

Console.log is showing...

this is the selected designer null

And a codesandbox with dummy data

https://codesandbox.io/s/lucid-bassi-r0lrd?file=/src/Filter.js:0-875


Solution

  • You'll have to call onchange on select tag

     return (
            <div className="ProductFilter">
              <select onChange={(e => {
                      console.log('this is on change', e);
                      setSelectedDesigner(e.target.value)})}>
              {designerData.map((designer, id) => {
                return (
                  <option
                    value={[designer.brand.name]}
                  >
                    {[designer.brand.name]}
                  </option>
                );
              })}
              </select>
              <h1>this is the selected designer {selectedDesigner}</h1>
            </div>
          );