什么是Hooks?
Hooks是react即将推出的功能,它容许您在不编写类的状况下使用状态和其余React功能。
个人理解就是能够用写无状态组件的方式去编写拥有状态的组件。
遗憾的是,正式版16.7.0出了以后并无hooks,若是须要体验还需下载next版本,目前是16.7.0-alpha.2前端
npm i react@next 此次与你们分享四个Hooks,我的以为这几个应该是以后工做中会常用到的。 1. useState 2. useEffect 3. useReducer 4. useMemo
1.useState
我的感受这个钩子是重点,使用它便可作到用函数的编写带有状态的组件。react
import React,{ useState,useEffect } from 'react' const HookTest = () => { const [obj,setValue] = useState({key:'count',value:0}); const handleChange = () => { const value = obj.value+1; //改变状态 setValue(Object.assign(obj,{value})); } return ( <div> {obj.key}:{obj.value} <p> <button onClick={handleChange}>累加</button> </p> </div> ) }
很明显,重点在于const [obj,setValue] = useState({key:'count',value:0})这一句,useState是个函数,接收一个状默认值,返回一个数组,第一个元素为状态,初始值为传入函数的默认值,第二个元素为方法,可以使用此方法改变状态的值。git
2.useEffect
这个钩子,官方所说是componentDidMount,componentDidUpdate和componentWillUnmount这三个生命周期的结合,由于组件挂载完成时会执行,更新时会执行,卸载时会执行,接上面的HookTest组件,往里添加github
useEffect(()=>{ console.log('obj->',obj); return ()=>{ console.log('卸载时..'); } });
这就是一个基本用法,挂载、更新、卸载都会打印obj对象,return的函数,做为组件更新或者卸载时执行,好比在使用setinterval,能够在return的函数里写clearinterval。
若是只想让它执行一次的话,能够往函数里添加第二个参数。npm
useEffect(()=>{ console.log('obj->',obj); },false);
这样只在挂载完成时执行一次,第二个参数能够为false、[]、{}、""
若是想让他有条件的执行,能够往第二个参数传入具体的参数redux
useEffect(()=>{ console.log('obj->',obj); },{obj.value});
若是obj.value值变化时,就执行,没变化时就不执行,对于性能优化很是友好。数组
3.useReducer性能优化
若是使用过redux的童鞋们不会默认,将须要的状态保存到一个对象中,可供全部的组件使用。
先上代码异步
import React, { useReducer,useMemo,useEffect,useState } from 'react'; //建立reducer,reducer可在外部建立而后再引入 function reducer(state = { count: 0 }, action) { switch (action.type) { case 'reset': return { count: 0 }; case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count <= 0 ? 0 : state.count - 1 }; default: return state; } } //组件 const useReducerDemo = () => { const [state, dispatch] = useReducer(reducer, { count: 0 }, { type: 'increment' }); //异步增长 const asyncIncrement = () => { setTimeout(()=>{ dispatch({ type: 'increment' }) },2000); } return ( <div> <p> <span>Count: {state.count}</span> <button onClick={() => dispatch({ type: 'reset' })}>还原</button> <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> <button onClick={asyncIncrement}>async+</button> </p> </div> ) }
能够看到,和useState很像,也是使用一个数组解构接受返回的值。
先说返回的值:
1.state
天然为reducer的状态
2.dispatch
这个是一个函数,有dispatch就意味着咱们能够不用像使用redux时还须要本身下中间件(如redux-thunk)就能够进行异步操做,具体看asyncIncrement函数,参数为一个对象,指定须要执行的action
再说useReducer函数的参数:
第一个参数为你引入的reducer,第二个参数为state的默认值,第三个参数为初始触发的action,就是载入时默认就执行一个actionasync
4.useMemo
useMemo只有当其中一个输入发生变化时,才会从新计算记忆值。此优化有助于避免在每一个渲染上进行昂贵的计算。
此钩子也是有助于性能优化,接入上面的useReducerDemo组件,往里添加
const [tips,setTips] = useState(false); //当为0时提示不能再减了 useEffect(()=>{ if(!state.count){ setTips(true); }else{ setTips(false); } }); const memoizedValue = useMemo(() => { console.log('useMemo run'); return tips }, [tips]);
在return组件元素div里添加
{ memoizedValue && <p>不能为负数哦</p> }
以上新增的代码时为了实如今reducer里的count小于等于0或从0变动为其余数字时更新true或false,以此达到p元素的显示与否,不然一直为上一次计算获得值,咱们使用了console.log('useMemo run');记录它更新的次数,当count从0一直+1,只会打印一次'useMemo run',由此说明,只在0变成1的时候执行了一次,日后memoizedValue的值一直为0变成1时所return的值。
此例子并说明不了什么,不过当有很庞大计算量的时候就能体现出useMemo的做用了。
useMemo一样也是一个函数,接受两个参数,第一个参数为函数,第二个参数为要比对的值,返回一个值。
第二个参数里能够传入多个值,如[a,b,c,...],当传入的这些值有变化时,就会去执行第一个传入的函数,根据业务需求计算后返回最终结果。
同理,第二个参数传入的值没有更新时,不会执行。
结尾
花了一下午的时间体验hook,其余的钩子也使用了个遍,感受这四个在我看来和在我公司业务里可能会大量的使用到,因此发此文章分享,也为记录,本人新手前端一枚,第一次写文章,有说的不对的地方还请请多多指教。
谢谢你们的阅读。
以上代码的github地址为react-hooks初体验