Как реализовать несколько флажков, используя ответный хук - PullRequest
0 голосов
/ 23 мая 2019

Я хочу установить несколько флажков на моей HTML-странице с помощью response-hook.

Я попытался реализовать, используя этот URL: https://medium.com/@Zh0uzi/my-concerns-with-react-hooks-6afda0acc672. В предоставленной ссылке это сделано с использованием компонента класса и работает отличноно всякий раз, когда я использую React-хук setCheckedItems для обновления статуса, отмеченного флажками, он не перерисовывает представление.

Самый первый раз, когда представление рендерится, а console.log () печатает из компонента Checkbox.После установки флажка вызывается функция handleChange , а checkedItems обновляет значение, но представление не визуализируется снова (печать console.log () отсутствует).И {checkItems.get ("check-box-1")} также не печатает никаких значений.

Ниже приведен мой пример кода.

CheckboxExample:

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;

Флажок :

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;

Ответы [ 2 ]

2 голосов
/ 23 мая 2019

Я не думаю, что лучше использовать Map для представления состояния.
Я реализовал ваш пример, используя простой Object, и он работает:

https://codesandbox.io/s/react-hooks-usestate-xzvq5

const CheckboxExample = () => {
  const [checkedItems, setCheckedItems] = useState({}); //plain object as state

  const handleChange = (event) => {
      // updating an object instead of a Map
      setCheckedItems({...checkedItems, [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["check-box-1"]} </lable> <br/>
          {
              checkboxes.map(item => (
                  <label key={item.key}>
                      {item.name}
                      <Checkbox name={item.name} checked={checkedItems[item.name]} onChange={handleChange} />
                  </label>
              ))
          }
      </div>
  );
}

EDIT:

Оказывается, Map может работать как значение состояния, но для запуска повторного рендеринга вам нужно заменить Карту на новую, вместо того, чтобы просто поменять ее, что не выбрано React, то есть:

const handleChange = (event) => {
  // mutate the current Map
  checkedItems.set(event.target.name, event.target.checked)
  // update the state by creating a new Map
  setCheckedItems(new Map(checkedItems) );
  console.log("checkedItems: ", checkedItems);
}

но в этом случае я думаю, что нет никакой пользы от использования карты, кроме, возможно, более чистого синтаксиса с .get() и .set() вместо x[y].

0 голосов
/ 23 мая 2019

Кажется, немного далеко, но если вы развернете карту и примените ее к new Map, ваш компонент будет повторно визуализирован.Я думаю, что здесь лучше всего использовать ссылку на объект вместо Map.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...