useState()是一个React钩子。钩子使得在函数组件中使用状态和可变性成为可能。
虽然不能在类内部使用钩子,但可以用函数1包装类组件并从中使用钩子。这是将组件从类形式迁移到函数形式的一个很好的工具。下面是一个完整的例子:
对于本例,我将使用计数器组件。就是这样:
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick={() => this.inc()}>{this.state.count}</button>
}
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<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>
<div id='root'></div>
它是一个具有计数状态的简单类组件,状态更新由方法完成。这是类组件中非常常见的模式。第一件事是用同名的函数组件包装它,该函数组件将其所有属性委托给被包装的组件。此外,您还需要在函数return中呈现被包装的组件。下面就是:
function Hello(props) {
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick={() => this.inc()}>{this.state.count}</button>
}
}
return <Hello {...props}/>
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<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>
<div id='root'></div>
这是完全相同的组件,具有相同的行为、相同的名称和相同的属性。现在让我们将计数状态提升到函数组件。事情是这样的:
function Hello(props) {
const [count, setCount] = React.useState(0);
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick={() => setCount(count+1)}>{count}</button>
}
}
return <Hello {...props}/>
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
注意,方法inc仍然在那里,它不会伤害任何人,实际上是死代码。就是这样,不断提升状态。一旦你完成,你可以删除类组件:
function Hello(props) {
const [count, setCount] = React.useState(0);
return <button onClick={() => setCount(count+1)}>{count}</button>;
}
ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>
虽然这使得在类组件中使用钩子成为可能,但我不建议您这样做,除非您像我在本例中那样迁移。混合函数和类组件将使状态管理变得混乱。我希望这对你们有帮助
致以最亲切的问候