React Hooks初探(一)

253 阅读2分钟

hooks引入react里已经很长时间了,在项目中一直使用,文档也没仔细阅读,今天打算再重新看看文档,领略一下当初学习的感受。

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

我们都不知道Hooks做的事情:让你在函数组件里体验class组件的功能。今天主要介绍一下useStateuseEffect两个非常基础的hooks

useState

语法:const [state,setState] = useState(initValue);

首先,我们来看一个非常基础的class组件的例子:

class classComp extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            counter: 0
        };  
    }
    render(){
        return <div>
        <div>{ count }</div>
        <button onClick={()=>{ 
            this.setState((state, props) => ({
              counter: state.counter + 1
            }));
        }}>增加</button>
    </div>
    }
}

那么,如果使用useState怎么写?

const fnComp = () => {
    const [counter,setCounter] = useState(0);
    return <div>
        <div>{ counter }</div>
        <button onClick={()=>{ setCounter(counter+1) }}>增加</button>
    </div>
}

非常容易理解,该钩子接收一个初始值,返回一个state的引用,加上该state的setter方法。

所以对于该钩子只需要关注三个部分:

  • 初始值
  • 状态引用
  • 状态的更新方法(setter)

useEffect

相信大家对于React的Class组件的两个生命周期钩子很熟悉:componentDidMountcomponentDidUpdate,一个在组件挂载到DOM里时调用,一个在组件的数据(state)发生变化时调用。

这两个生命周期函数在hooks里对应着useEffect钩子。

class组件两个生命周期钩子的使用:

class Example extends React.Component {
  //省略代码
  componentDidMount() {    
      document.title = `You clicked ${this.state.count} times`;  
  }  
  componentDidUpdate() {    
      document.title = `You clicked ${this.state.count} times`;  
  }
  //省略代码
}

函数组件里的使用useEffect:

const Example = () => {
    useEffect(()=>{
        document.title = `You clicked ${this.state.count} times`;  
    })
}

代码精简多了,不是吗?

然而,有的时候,我们会在组件加载时(mount)执行一些操作,然后组件销毁时(unmount)做一些清理。如果我们使用useEffect怎么实现这种需求呢?

const Example = () => {
    //不需要清理
    useEffect(()=>{
        document.title = `You clicked ${this.state.count} times`; 
    })
    
    //需要清理(返回清理函数)
    useEffect(()=>{
        const timer = setInterval(()=>{
            console.log("run!!!")
        },1000)
        return ()=>{
            clearInterval(timer);
        }
    })
}

注意:useEffect清理函数会在每次render之前清理上次的render,也会在组件unmount时清理。

还有一种场景,就是我们可能需要在某些state改变时才去执行 useEffect钩子,这该怎么办呢?

useEffect(() => {
  //只会在count发生更改时执行
  document.title = `You clicked ${count} times`;
}, [count]);

最后一个场景,我们只想在组件加载时执行,更新时不执行,该怎么办呢?官网上貌似没提到

其实很简单啦,我们只需要给useEffect传入一个空数组作为第二个参数,表示不依赖任何的state,任何state变化都不会导致更新,不刚好就是mount的意思吗?

useEffect(() => {
  //只会在组件componentDidMount时执行
  document.title = `You clicked ${count} times`;
}, []);

未完待续

感谢阅读