web-dev-qa-db-fra.com

Comment implémenter plusieurs cases à cocher à l'aide de React Hook

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;
6
Nakesh

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>
1
Francis Leigh

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));
1
rodamn