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 ondiv
document.querySelector
anddocument.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
- Include the
.map
is being used like.forEach
setItem([...item, element.value])
is called for everyelement
regardless of your conditionfiltre
is misspelled
item
is derived state that should not have its own state- Use
data.filter
to computeitem
- See Single Source of Truth
- Use
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;
})
}
}
>