Home > OS >  React useState, how to reset to initial value
React useState, how to reset to initial value

Time:02-18

I have a problem in this code. I need reset item array in line but don't work.

 if (!(element.name in filter){setItem([])}
function MainElement() {
   const [data, setData] = useState([]);
   const [filter, setFilter] = useState({});
   const [item, setItem] = useState([]);

  useEffect( () => {
    fetchData("http://localhost/product.php")
      .then( category => {
        setData(category);
    });
  }, [])

  return (
    <div onChange={
      (e) => {
        const selection = document.querySelectorAll('input[type="checkbox"]:checked');
        [...selection].map((element) => {
          if (!(element.name in filter){setItem([])}
          setItem([...item, element.value])
          return  filtre[element.name]=item;
        })
      }
    }
    >

CodePudding user response:

There is a list of things worth fixing in your codes.

  • onChange has no effect on div
  • document.querySelector and document.querySelectorAll should not be used inside a React component
    • Include the <input> checkboxes as part of your app
    • See useRef if you must reference other elements
  • .map is being used like .forEach
    • setItem([...item, element.value]) is called for every element regardless of your condition
    • filtre is misspelled
  • item is derived state that should not have its own state

Here is a minimal complete example you can run in your browser.

function fetchProducts() {
  return new Promise(resolve =>
    setTimeout(resolve, 1000, [
      {"name": "carrot", type: "vegetable", quantity: 6 },
      {"name": "potato", type: "vegetable", quantity: 0 },
      {"name": "pretzels", type: "snack", quantity: 3 }
    ]))
}

function App() {
  const [products, setProducts] = React.useState([])
  const [isVegetable, veggieFilter] = useCheckbox(false)
  const [isStocked, stockFilter] = useCheckbox(false)
  React.useEffect(_ => {
    fetchProducts().then(setProducts).catch(console.error)
  }, [])
  function filter() {
    return products
      .filter(p => !isVegetable || p.type == "vegetable")
      .filter(p => !isStocked || p.quantity > 0)
  }
  return <div>
    Vegetable:{veggieFilter} In-Stock:{stockFilter}
    {filter().map(p => <pre>{JSON.stringify(p)}</pre>)}
  </div>
}

function useCheckbox(initValue = false) {
  const [checked, setChecked] = React.useState(initValue)
  return [
    checked,
    <input type="checkbox" checked={checked} onClick={_ => setChecked(!checked)} />
  ]
}

ReactDOM.render(<App/>, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

CodePudding user response:

You are executing setItem([...item, element.value]) everytime. You should either do it , or

<div onChange={
      (e) => {
        const selection = document.querySelectorAll('input[type="checkbox"]:checked');
        [...selection].map((element) => {
          if (!(element.name in filter){return setItem([])} // I added a return, so we exit the function
          setItem([...item, element.value])
          return  filtre[element.name]=item;
        })
      }
    }
>
  • Related