Не могу снять все флажки - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть список флажков и еще один флажок вверху, чтобы проверить их все, но когда я проверяю их все, я больше не могу их очистить.

class App extends React.Component {
  state = { checked: undefined }
  selectAll = ({ target: { checked } }) => this.setState({ checked })

  render() {
    const { checked } = this.state
    const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    return <ul>
      <input type='checkbox' onChange={this.selectAll} /> Check All
      {arr.map(i => <li>
        <input type='checkbox' checked={checked} />
        <span>checkbox {i}</span>
      </li>
      )}
    </ul>
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Ответы [ 3 ]

3 голосов
/ 28 февраля 2020

Вам нужно будет контролировать каждый флажок, чтобы выполнить sh это. В противном случае ваши флажки имеют контролируемые значения только после выбора опции «Выбрать все».

Я бы сохранил ваши флажки в виде массива объектов в состоянии и сделал бы что-то вроде этого:

class App extends React.Component {
  state = { 
    boxes: [
      {name: 0, checked: false}, 
      {name: 1, checked: false}, 
      {name: 2, checked: false}, 
      {name: 3, checked: false}, 
      {name: 4, checked: false}, 
      {name: 5, checked: false}, 
      {name: 6, checked: false}, 
      {name: 7, checked: false}, 
      {name: 8, checked: false}, 
      {name: 9, checked: false},
    ]
  }
  
  selectAll = (e) => {
   // Loop through every box and set checked to the value of the current checkbox
    e.persist();
    this.setState(prevState => ({ 
      boxes: prevState.boxes.map(value => (
        {...value, checked: e.target.checked }
      ))
    }))
  }
  
  handleCheck = (e, name) => {
    // Loop through each box and change the value of the corresponding box
    e.persist();
    this.setState(prevState => (
      { 
        boxes: prevState.boxes.map((value) => {
          if (name == value.name) {
            return {...value, checked: e.target.checked};
          }
          return value;
        })
      }
    ))
  }

  render() {
    return <ul>
      <input type='checkbox' onChange={this.selectAll} /> Check All
      {this.state.boxes.map(value => (
       <li key={value.name}>
         <input 
           type='checkbox' 
           checked={value.checked} // Now value is informed by state
           // Pass the event and name to handler
           onChange={(e) => this.handleCheck(e, value.name)} 
          />
          <span>checkbox {value.name}</span>
        </li>
      ))}
    </ul>
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
2 голосов
/ 28 февраля 2020

Переработано, но это лучшее решение, где оно обрабатывает также действие, если выбраны все флажки, будет установлен флажок select all.

Этот фрагмент основан на этом

function CheckBox({name, value, tick, onCheck}) {
      return (
          <label>
              <input
                  
                  type="checkbox"
                  value={value}
                  checked={tick || false}
                  onChange={onCheck}
              />
              {value}
          </label>
      );
  }


function CheckBoxList ({options, isCheckedAll, onCheck}) {
    const checkBoxOptions = (
        <div className="checkbox-list">
            {options.map((option, index) => {
                return (
                    <CheckBox
                      key={index}
                      value={option.value}
                      tick={option.checked}
                      onCheck={(e) => onCheck(option.value, e.target.checked)}                     />
                );
            })}
        </div>
    );

    return (
        <div className="checkbox-list">
            <CheckBox
              name="select-all"
              value="ALL"
              tick={isCheckedAll}
              onCheck={(e) => onCheck('all', e.target.checked)}
            />
            {checkBoxOptions}
        </div>
    );
}

class List extends React.Component {
    //constructor(props) {
      //  super(props);

        state = {
            isAllSelected: false,
            checkList: [
                {
                    value: 1,
                    checked: false,
                },
                {
                    value: 2,
                    checked: false,
                },
                {
                    value: 3,
                    checked: false,
                }
            ]
        };
    //}

    onCheckBoxChange(checkName, isChecked) {
        let isAllChecked = (checkName === 'all' && isChecked);
        let isAllUnChecked = (checkName === 'all' && !isChecked);
        const checked = isChecked;

        const checkList = this.state.checkList.map((item, index) => {
            if(isAllChecked || item.value === checkName) {
                return Object.assign({}, item, {
                    checked,
                });
            } else if (isAllUnChecked) {
                return Object.assign({}, item, {
                    checked: false,
                });
            }

            return item;
        });

        let isAllSelected = (checkList.findIndex((item) => item.checked === false) === -1) || isAllChecked;

        this.setState({
            checkList,
            isAllSelected,
        });

    }

    render() {
        return (
          <div className="list">
            <CheckBoxList 
                options={this.state.checkList}
                isCheckedAll={this.state.isAllSelected}
                onCheck={this.onCheckBoxChange.bind(this)} 
            />
          </div>
        );
    }
}

ReactDOM.render(<List />, document.getElementById('root'))
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
2 голосов
/ 28 февраля 2020

Это произошло, поскольку одно и то же состояние checked используется всеми флажками, а также вы не установили какой-либо обработчик событий для обновления состояния при нажатии любого из флажков. Таким образом, вы не можете снять все флажки.

Вот одно решение для решения этой проблемы, но установка отдельного проверенного состояния для каждого текстового поля, чтобы изменение одного не влияло на другие вообще, кроме как при нажатии Отметить все .

class App extends React.Component {
  state = { checkboxes: [{id:1, checked: false}, {id:2, checked: false}, {id:3, checked: false}] }
  selectAll = ({ target: { checked } }) => {
    let { checkboxes } = this.state
    checkboxes.forEach(chk => chk.checked = checked) 
    this.setState({checkboxes})
  }
  
  select = ({ target: { value, checked } }) => {
    let { checkboxes } = this.state
    checkboxes.forEach(chk => {
       if (chk.id === +value) chk.checked = checked;
    })
    this.setState({checkboxes: checkboxes})
  }


  render() {
    const { checkboxes } = this.state
    return <ul>
      <input type='checkbox' onChange={this.selectAll} /> Check All
      {checkboxes.map(i => <li>
        <input type='checkbox' checked={i.checked} onClick={this.select} value={i.id}/>
        <span>Checkbox {i.id}</span>
      </li>
      )}
    </ul>
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...