在 React 中将类组件转换为功能组件

IT技术 javascript reactjs react-hooks use-state
2021-05-17 15:08:02

我正在学习 React 钩子,所以为了做到这一点,我试图将类组件转换为功能组件,但我仍然遇到一些错误。

这是作为类编写的原始工作组件:

import React, { Component } from 'react';
import NavBar from './components/navbar';
import Counters from './components/counters';

class App extends Component {
  state = {
    counters: [
      { id: 0, value: 5 },
      { id: 1, value: 1 },
      { id: 2, value: 2 },
    ],
  };

  handleDelete = (counterId) => {
    const counters = this.state.counters.filter((c) => c.id !== counterId);
    this.setState({ counters });
  };

  handleReset = () => {
    const counters = this.state.counters.map((c) => {
      c.value = 0;
      return c;
    });
    this.setState({ counters });
  };

  handleIncrement = (counter) => {
    const counters = [...this.state.counters];
    const index = counters.indexOf(counter);
    counters[index] = { ...counter };
    counters[index].value++;
    this.setState({ counters });
  };
  render() {
    return (
      <React.Fragment>
        <NavBar
          totalCounters={this.state.counters.filter((c) => c.value > 0).length}
        />
        <main className='container'>
          <Counters
            counters={this.state.counters}
            onReset={this.handleReset}
            onDelete={this.handleDelete}
            onIncrement={this.handleIncrement}
          />
        </main>
      </React.Fragment>
    );
  }
}

export default App;

这是使用钩子的转换版本。

 import React, { useState } from 'react';
    import NavBar from './components/navbar';
    import Counters from './components/counters';
    
    const App = () => {
      const [counters, setCounters] = useState([
        { id: 0, value: 5 },
        { id: 1, value: 1 },
        { id: 2, value: 2 },
      ]);
    
      const handleDelete = (counterId) => {
        const counterss = counters.filter((c) => c.id !== counterId);
        setCounters({ counterss });
      };
    
      const handleReset = () => {
        const counterss = counters.map((c) => {
          c.value = 0;
          return c;
        });
        setCounters({ counterss });
      };
    
      const handleIncrement = (counter) => {
        const counterss = [...counters];
        const index = counterss.indexOf(counter);
        counterss[index] = { ...counter };
        counterss[index].value++;
        setCounters({ counterss });
      };
    
      return (
        <React.Fragment>
          <NavBar totalCounters={counters.filter((c) => c.value > 0).length} />
          <main className='container'>
            <Counters
              counters={counters}
              onReset={handleReset}
              onDelete={handleDelete}
              onIncrement={handleIncrement}
            />
          </main>
        </React.Fragment>
      );
    };
    
    export default App;

它的大部分工作正常,但它不断抛出一个错误,说过滤器不是一个函数。这是消息:

类型错误:counters.filter 不是函数

3个回答

罪魁祸首似乎是您更新状态的方式,如下所示:

setCounters({ counterss });

这实际上会将您的counters状态设置为具有属性的对象counterss,因此您的状态将包含以下内容:

{ counterss: [/* rest of the array */] }

抛出的确切错误是指您试图调用.filter对象而不是数组的事实要解决此问题,您应该简单地更新您的状态,如下所示:

setCounters(counterss);
setCounters({ counterss })

应该

setCounters(counterss)

它会引发错误,因为您将新状态设置为 object setCounters({ counterss });但是你想要一个数组:setCounters(counterss);这样它不会在第二次setCounters调用时抛出错误