React Hook 版本及使用规则
版本React 16.8及以上
使用规则:
- 只能在函数最外层调用Hook。不要在循环、条件判断或者子函数中调用。(React依靠hook的调用顺序来确定哪个state对应哪个hook。因此在写代码的过程中,要保证hook的调用顺序在每次渲染中都是相同的。确保它能正常运行)
- 只能在 React 的函数组件中调用 Hook。 在自定义 Hook 中调用其他 Hook.不要在其他 JavaScript 函数中调用。
useState:
const [xxx, setxxx] = useState(initialState)
Class组件写法
import React, {
Component } from 'react';
class Example extends Component{
constructor(){
super();
this.state = {
count: 0
}
}
render() {
return (
<div>
<h2>You clicked {
this.state.count } times</h2>
<button onClick={
() => {
this.setState({
count: this.state.count + 1})}}>Click me</button>
</div>
);
}
}
export default Example;
Hook写法
import React, {
useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return(
<div>
<h2>You clicked {
count } times</h2>
<button onClick={
() => {
setCount(count + 1)}}>Click me</button>
</div>
);
}
export default Example;
知识点总结:
- useState
只有唯一的参数,用于给state初始化赋值。两个返回值,一个是state,一个是用于更新state的函数(可以理解为每个state有了自己的this.setState.).
通常我们使用数组解构赋值来获取这两个返回值, 例如: const [count, setCount] = useState(0); - useState需成对出现,需要多少state和对应的更新state函数,就声明多少次。
- React依靠hook的调用顺序来确定哪个state对应哪个useState。因此在写代码的过程中,要保证hook的调用顺序在每次渲染中都是相同的。确保它能正常运行
- useState不会自动合并更新对象,需要用函数式的方式来达到效果
setCount(prevCount => {
// 也可以使用 Object.assign
return {
...prevCount, ...updatedValues};
});
- state初始化参数既可以是值,也可以是一个函数(返回初始的state)。此函数只在初始渲染时被调用。
const [count, setCount] = useState(() => {
const initialCount = someComputation(props);
return initialCount;
});
useEffect
effect分类
无需清除的effect
比如发送网络请求,手动变更 DOM,记录日志、
需要清除的effect
例如订阅外部数据源,监听器,定时器
无需清除的effect Class组件写法
import React, {
Component} from 'react';
class Example extends Component{
constructor(props){
super(props);
this.state = {
count: 0
}
}
componentDidMount(){
console.log(`You clicked ${
this.state.count} times`);
}
componentDidUpdate(){
console.log(`You clicked ${
this.state.count} times`);
}
render(){
return(
<div>
<h2>You clicked {
this.state.count} times</h2>
<button onClick={
() => {
this.setState({
count: this.state.count + 1})}}>Click me</button>
</div>
);
}
}
export default Example;
无需清除的effect Hook
import React, {
useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(()=>{
console.log(`You clicked ${
count} times`);
});
return(
<div>
<h2>You clicked {
count} times</h2>
<button onClick={
() => {
setCount(count + 1)}}>Click me</button>
</div>
);
}
export default Example;
需清除的effect Class组件写法
import React, {
Component} from 'react';
class Example extends Component{
constructor(props){
super(props);
this.state = {
innerWidth: 0,
innerHeight: 0
};
this.handleWindowSizeChange = this.handleWindowSizeChange.bind(this);
}
componentDidMount(){
window.addEventListener('resize', this.handleWindowSizeChange);
}
componentWillUnmount(){
window.removeEventListener('resize', this.handleWindowSizeChange);
}
handleWindowSizeChange(){
this.setState({
innerWidth: window.innerWidth,
inner