Как преобразовать компонент на основе класса в компонент на основе функции? - PullRequest
1 голос
/ 18 апреля 2020

Сейчас у меня есть компонент на основе классов, но я хочу преобразовать свой компонент в функциональный. Код ниже здесь. Я выбрал все флажки, написанные в компоненте на основе классов. но теперь я хочу преобразовать этот компонент в функциональный, я изменил все методы и реквизиты в своем коде, но есть некоторая ошибка состояния. Я не получаю возможную ошибку.

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Checkbox } from 'antd';

const CheckboxGroup = Checkbox.Group;

const plainOptions = ['Apple', 'Pear', 'Orange'];
const defaultCheckedList = ['Apple', 'Orange'];

class App extends React.Component {
  state = {
    checkedList: defaultCheckedList,
    indeterminate: true,
    checkAll: false,
  };

  onChange = checkedList => {
    this.setState({
      checkedList,
      indeterminate: !!checkedList.length && checkedList.length < plainOptions.length,
      checkAll: checkedList.length === plainOptions.length,
    });
  };

  onCheckAllChange = e => {
    this.setState({
      checkedList: e.target.checked ? plainOptions : [],
      indeterminate: false,
      checkAll: e.target.checked,
    });
  };

  render() {
    return (
      <div>
        <div className="site-checkbox-all-wrapper">
          <Checkbox
            indeterminate={this.state.indeterminate}
            onChange={this.onCheckAllChange}
            checked={this.state.checkAll}
          >
            Check all
          </Checkbox>
        </div>
        <br />
        <CheckboxGroup
          options={plainOptions}
          value={this.state.checkedList}
          onChange={this.onChange}
        />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));

now I am converting my component into function-based. but having an issue. Can anybody suggest me the possible mistake, please ... the checkbox is showing all options but unable to check the box or cant check all options at once. Can anybody suggest me some answer so I can solve my issue?

import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Checkbox } from 'antd';

const CheckboxGroup = Checkbox.Group;

const plainOptions = ['Apple', 'Pear', 'Orange'];
const defaultCheckedList = ['Apple', 'Orange'];

function App (props) {
  state = {
    checkedList: defaultCheckedList,
    indeterminate: true,
    checkAll: false,
  };

  const onChange = checkedList => {
    this.setState({
      checkedList,
      indeterminate: !!checkedList.length && checkedList.length < plainOptions.length,
      checkAll: checkedList.length === plainOptions.length,
    });
  };

  const onCheckAllChange = e => {
    this.setState({
      checkedList: e.target.checked ? plainOptions : [],
      indeterminate: false,
      checkAll: e.target.checked,
    });
  };


    return (
      <div>
        <div className="site-checkbox-all-wrapper">
          <Checkbox
            indeterminate={this.state.indeterminate}
            onChange={this.onCheckAllChange}
            checked={this.state.checkAll}
          >
            Check all
          </Checkbox>
        </div>
        <br />
        <CheckboxGroup
          options={plainOptions}
          value={this.state.checkedList}
          onChange={this.onChange}
        />
      </div>
    );

}

ReactDOM.render(<App />, document.getElementById('container'));

Ответы [ 3 ]

1 голос
/ 18 апреля 2020

В компонентах класса вы просто пишете объект состояния 'this.state' и описываете состояния этого объекта, но в функциональных компонентах все немного по-другому.

Вы должны использовать ловушки React, и вы должны установить каждое отдельное состояние с константами массива.

Если мы предположим, что код полностью свободен от ошибок и ошибок, код будет выглядеть следующим образом:

(обратите внимание, что «this.» только используется в компонентах класса)

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Checkbox } from 'antd';

const CheckboxGroup = Checkbox.Group;

const plainOptions = ['Apple', 'Pear', 'Orange'];
const defaultCheckedList = ['Apple', 'Orange'];


function App(props) {
  const [checkedList, setCheckedList] = useState(defaultCheckedList);
  const [indeterminate, setIndeterminate] = useState(true);
  const [checkAll, setCheckAll] = useState(false);

  const onChange = event => {
    setCheckedList(event);
    setIndeterminate(!!event.length && event.length < plainOptions.length)
    setCheckAll(event.length === plainOptions.length)
  };

  const onCheckAllChange = e => {
    setCheckedList(e.target.checked ? plainOptions : []);
    setIndeterminate(false);
    setCheckAll(e.target.checked);
  };


  return (
    <div>
      <div className="site-checkbox-all-wrapper">
        <Checkbox
          indeterminate={indeterminate}
          onChange={onCheckAllChange}
          checked={checkAll}
        >
          Check all
              </Checkbox>
      </div>
      <br />
      <CheckboxGroup
        options={plainOptions}
        value={checkedList}
        onChange={onChange}
      />
    </div>
  );

}

ReactDOM.render(<App />, document.getElementById('container'));

Второй аргумент массива изменяет количество первого аргумента, а затем вызывает API обновления экрана.

Вы можете узнать больше о жизненных циклах функционала компоненты в React Docs .

0 голосов
/ 18 апреля 2020

Заменить:

state = {
  checkedList: defaultCheckedList,
  indeterminate: true,
  checkAll: false,
};

на:

const [checkedList, setCheckedList] = React.useState(defaultCheckedList);
const [indeterminate, setIndeterminate] = React.useState(true);
const [checkAll, setCheckAll] = React.useState(false);

Чтобы отобразить состояние, просто используйте первый элемент:

<div>{indeterminate}</div>

Чтобы изменить состояние, используйте второй предмет:

setIndeterminate(false);
0 голосов
/ 18 апреля 2020

В компоненте функции, вы не можете использовать состояние таким образом !

До того, как сработали хуки, у вас не было возможности иметь внутренние компоненты функции состояния. К счастью, после 16,8 в реакции у вас есть React Hooks !

В вашем случае вы должны использовать useState (); hook и ваш текущий State вставьте этот хук.

import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Checkbox } from 'antd';

const CheckboxGroup = Checkbox.Group;

const plainOptions = ['Apple', 'Pear', 'Orange'];
const defaultCheckedList = ['Apple', 'Orange'];

function App (props) {
  const [state, setState] = useState({
    checkedList: defaultCheckedList,
    indeterminate: true,
    checkAll: false,
  });

  const onChange = checkedList => {
    setState({
      checkedList,
      indeterminate: !!checkedList.length && checkedList.length < plainOptions.length,
      checkAll: checkedList.length === plainOptions.length,
    });
  };

  const onCheckAllChange = e => {
    setState({
      checkedList: e.target.checked ? plainOptions : [],
      indeterminate: false,
      checkAll: e.target.checked,
    });
  };


    return (
      <div>
        <div className="site-checkbox-all-wrapper">
          <Checkbox
            indeterminate={state.indeterminate}
            onChange={onCheckAllChange}
            checked={state.checkAll}
          >
            Check all
          </Checkbox>
        </div>
        <br />
        <CheckboxGroup
          options={plainOptions}
          value={state.checkedList}
          onChange={onChange}
        />
      </div>
    );

}

ReactDOM.render(<App />, document.getElementById('container'));

Другое ключевое слово this, у вас есть только компонент в классе.

...