Je souhaite implémenter plusieurs cases à cocher sur ma page HTML à l'aide de react-hook.
J'ai essayé d'implémenter en utilisant cette URL: https://medium.com/@Zh0uzi/my-concerns-with-react-hooks-6afda0acc672 . Dans le lien fourni, cela se fait en utilisant le composant de classe et fonctionne parfaitement, mais chaque fois que j'utilise React hook setCheckedItems pour mettre à jour le statut de la case à cocher, il ne restitue pas la vue.
La toute première fois que la vue est rendue et console.log () imprime à partir du composant Checkbox. Après avoir cliqué sur la fonction checkbox , handleChange est appelé et checkedItems met à jour la valeur mais la vue n'est pas restituée (pas d'impression console.log ()). Et {checkedItems.get ("check-box-1")} n'imprime également aucune valeur.
Voici mon exemple de code.
Exemple de case à cocher :
import React, { useState } from 'react';
import Checkbox from '../helper/Checkbox';
const CheckboxExample = () => {
const [checkedItems, setCheckedItems] = useState(new Map());
const handleChange = (event) => {
setCheckedItems(checkedItems => checkedItems.set(event.target.name, event.target.checked));
console.log("checkedItems: ", checkedItems);
}
const checkboxes = [
{
name: 'check-box-1',
key: 'checkBox1',
label: 'Check Box 1',
},
{
name: 'check-box-2',
key: 'checkBox2',
label: 'Check Box 2',
}
];
return (
<div>
<lable>Checked item name : {checkedItems.get("check-box-1")} </lable> <br/>
{
checkboxes.map(item => (
<label key={item.key}>
{item.name}
<Checkbox name={item.name} checked={checkedItems.get(item.name)} onChange={handleChange} />
</label>
))
}
</div>
);
}
export default Example;
Case à cocher :
import React from 'react';
const Checkbox = ({ type = 'checkbox', name, checked = false, onChange }) => {
console.log("Checkbox: ", name, checked);
return (<input type={type} name={name} checked={checked} onChange={onChange} /> )
}
export default Checkbox;
Cela semble un peu long mais si vous étalez la carte et l'appliquez à un new Map
votre composant sera rendu à nouveau. Je pense que l'utilisation d'une référence d'objet au lieu d'un Map
fonctionnerait mieux ici.
const {useState} = React
const Mapper = () => {
const [map, setMap] = useState(new Map());
const addToMap = () => {
const RNDM = Math.random().toFixed(5)
map.set(`foo${RNDM}`, `bar${RNDM}`);
setMap(new Map([...map]));
}
return (
<div>
<ul>
{[...map].map(([v, k]) => (
<li key={k}>
{k} : {v}
</li>
))}
</ul>
<button onClick={addToMap}>add to map</button>
</div>
);
};
const rootElement = document.getElementById("react");
ReactDOM.render(<Mapper />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
En complément de l'utilisation d'un seul objet pour conserver l'état de nombreux éléments, les mises à jour ne se produiront pas comme prévu si la mise à jour plusieurs éléments dans un seul rendu. Les validations plus récentes dans le cycle de rendu écraseront simplement les validations précédentes .
La solution à cela est de regrouper toutes les modifications dans un seul objet et de les valider toutes en même temps, comme ceci:
// An object that will hold multiple states
const [myStates, setMyStates] = useState({});
// An object that will batch all the desired updates
const statesUpdates = {};
// Set all the updates...
statesUpdates[state1] = true;
statesUpdates[state2] = false;
// etc...
// Create a new state object and commit it
setMyStates(Object.assign({}, myStates, statesUpdates));