我正在学习React hooks,所以为了做到这一点,我试图将类组件转换为功能组件,但我仍然得到一些错误。
下面是作为类编写的原始工作组件:
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;
大部分都工作得很好,但它总是抛出一个错误,说过滤器不是一个函数。消息如下:
TypeError:计数器。Filter不是一个函数
罪魁祸首似乎是您更新状态的方式,如下所示:
setCounters({ counterss });
这实际上会将你的counters
状态设置为一个具有counterss
属性的对象,所以你的状态将包含以下内容:
{ counterss: [/* rest of the array */] }
抛出的确切错误是指您试图在对象而不是数组上调用.filter
。要解决这个问题,你应该简单地更新你的状态,像这样:
setCounters(counterss);
setCounters({ counterss })
应该
setCounters(counterss)
抛出错误,因为您将新状态设置为对象setCounters({ counterss });
。但你想要一个数组:setCounters(counterss);
。这样就不会在第二次调用setCounters
时抛出错误。