简体   繁体   中英

Convert class component to functional component in React

I'm learning React hooks so in order to do that I'm trying to convert a class component to a functional component but I still get some errors.

Here is the original working component written as a class:

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;

And this is the converted version which uses hooks.

 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;

Most of it works fine but it keeps throwing an error saying that filter is not a function. Here it is the message:

TypeError: counters.filter is not a function

The main culprit appears to be the way you are updating your state, which is like this:

setCounters({ counterss });

This will actually set your counters state to an object with the property counterss , so your state will contain the following:

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

The exact error being thrown is referring to the fact that you are attempting to call .filter on an object instead of an array. To fix this issue you should simply update your state like this:

setCounters(counterss);
setCounters({ counterss })

should be

setCounters(counterss)

It throws an error because you set the new state as an object setCounters({ counterss }); . But you want an array: setCounters(counterss); . This way it won't throw an error the second time setCounters is called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM