React-hooks API介绍

react-hooks HOOKS

  • hooks概念在React Conf 2018被提出来,并将在未来的版本中被引入,hooks遵循函数式编程的理念,主旨是在函数组件中引入类组件中的状态和生命周期,并且这些状态和生命周期函数也可以被抽离,实现复用的同时,减少函数组件的复杂性和易用性。
  • 函数组件 (functional component) 内部能够”钩住“ React 内部的 state 和 life-cycles。
  • 真正功能强大的地方是使我们能够更轻松地复用组件逻辑(custom hooks)
  • 让FunctionalComponent具有ClassComponent的功能

设计Hooks主要是解决ClassComponent的几个问题:

  • 很难复用逻辑(只能用HOC,或者render props),会导致组件树层级很深
  • 会产生巨大的组件(指很多代码必须写在类里面)
  • 类组件很难理解,比如方法需要bind,this指向不明确
 npm install react@16.7.0-alpha.2
 npm install react-dom@16.7.0-alpha.2

 npm install eslint-plugin-react-hooks@next
    // Your ESLint configuration
    {
    "plugins": [
        // ...
        "react-hooks"
    ],
    "rules": {
        // ...
        "react-hooks/rules-of-hooks": "error"
    }
    }

Hooks API Reference

   ** Basic Hooks **
    useState
    useEffect
    useContext

   ** Additional Hooks **
    useReducer
    useCallback
    useMemo
    useRef
    useImperativeMethods
    useMutationEffect
    useLayoutEffect

Rules of Hooks

  • 只能在顶层调用Hooks 。不要在循环,条件或嵌套函数中调用Hook
  • 只能在functional component中使用

State Hook

定义组件状态

  • 避免组件的 state 结构过于臃肿,能够独立处理每个 state
  • 写法非常直观,一眼就可以看出和这个 state 相关的两个变量
    const useStateExample = () => {
        const [count, setCount] = useState(0);
        const [list, setList] = useState([]);
        const [object, setObject] = useState({ name: 'lishishi', age: 28 });
    }

  • State Hooks的定义必须在函数组件的最高一级,不能在嵌套,循环等语句中使用

  • 一个函数组件可以存在多个State Hooks,并且useState返回的是一个数组,数组的每一个元素是没有标识信息的,完全依靠调用useState的顺序来确定哪个状态对应于哪个变量,所以必须保证使用useState在函数组件的最外层

  • 最主要的原因就是你不能确保这些条件语句每次执行的次数是一样的,也就是说如果第一次我们创建了state1 => hook1, state2 => hook2, state3 => hook3这样的对应关系之后,下一次执行因为something条件没达成,导致useState(1)没有执行,那么运行useState(2)的时候,拿到的hook对象是state1的,那么整个逻辑就乱套了,所以这个条件是必须要遵守的!

 const useStateExample = () => {
     if(Math.random() > 1) {
        const [count, setCount] = useState(0);
        const [list, setList] = useState([]);
     }else {
        const [object, setObject] = useState({ name: 'lishishi', age: 28 });
     }
    }

Effect Hook

实现生命周期 (life-cycles)

  • 类似 redux 中的 subscribe,每当 React 因为 state 或是 props 而重新 render 的之后,就会触发 useEffect 里的这个 callback listener(在第一次 render 和每次 update 后触发)
  • 在生命周期内做的操作很多都会产生一些 side-effect(副作用)的操作,比如更新 DOM,fetch 数据,等等。
    useEffect(() => {
        //componentDidMount和componentDidUpdate周期的函数体
        return ()=>{ 
        //componentWillUnmount周期的函数体
        }
    })
    // ---------------------
    useEffect(() => {
        //仅在componentDidMount的时候执行
    },[]);
    // -----------------------
    useEffect(() => {
        //仅在componentDidMount的时候执行
        //只有stateName\props.id的值发生改变
    },[stateName,props.id]);
   
    componentDidUpdate(prevProps, prevState) {
        if (prevState.count !== this.state.count) {
        }
         if (prevProps.id !== this.props.id) {
        }
    }

  • useEffect函数必须位于函数组件的最高一级
useState('Mary')           
useEffect(persistForm)    
useState('Poppins')       
useEffect(updateTitle)

Context Hook

替代了 <Context.Consumer> 使用 render props 的写法,使组件树更加简洁。

Reducer Hook

相当于组件自带的 redux reducer,负责接收 dispatch 分发的 action 并更新 state

配合hooks重新实现react-redux

useReducer + useContext 钩子上进行一层很简单的封装以达到和以往 react-redux \ redux-thunk \ redux-logger 类似的功能

    npm install react-hooks-redux

React.memo() React 16.6.0

  • PureComponent 要依靠 class 才能使用。而 React.memo() 可以和 functional component 一起使用
   const MySnowyComponent = React.memo(function MyComponent(props) {
   // only renders if props have changed!
   });

   // can also be an es6 arrow function
   const OtherSnowy = React.memo(props => {
   return <div>my memoized component</div>;
   });

   // and even shorter with implicit return
   const ImplicitSnowy = React.memo(props => (
   <div>implicit memoized component</div>
   ));

useRef

useCallBack

  • e.g. shouldComponentUpdate ; This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders
const memoizedCallback = useCallback(
 () => {
   doSomething(a, b);
 },
 [a, b],
);

useMemo

  • useMemo will only recompute the memoized value when one of the inputs has changed
  • useCallback(fn, inputs) is equivalent to useMemo(() => fn, inputs)
 const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useImperativeMethods

  • useImperativeMethods customizes the instance value that is exposed to parent components when using ref
  • useImperativeMethods(ref, createInstance, [inputs])

useMutationEffect useLayoutEffect useEffect 差别

  • useMutationEffect
    It fires synchronously before Layout phase i.e. during the same phase that React performs its DOM mutations. Use it to perform blocking custom DOM mutations without taking any DOM measurement/reading layout.

  • useLayoutEffect
    It fires synchronously after all DOM mutations but before Paint phase. Use this to read layout(styles or layout information) from the DOM and then perform blocking custom DOM mutations based on layout.

  • useEffect
    It runs after the render is committed to the screen i.e. after Layout and Paint phase. Use this whenever possible to avoid blocking visual updates

注意

  • 目前react-hot-loader不能和hooks一起使用

Mixin => HOC => Render Prop => hooks

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,406评论 1 33
  • 本文将开始详细分析如何搭建一个React应用架构。 一. 前言 现在已经有很多脚手架工具,如create-reac...
    字节跳动技术团队阅读 4,263评论 1 23
  • React.js 小书学习 之 【使用 JSX 描述 UI 信息】 从 JSX 到页面 过程图解:JSX 到页面过...
    zdlucky阅读 1,257评论 0 20
  • ——任何时候,都要攒足人品,相信爱情。 单身、大龄、博士,还会遇到理想中的爱情吗?会的。只要做好准备,攒足人品,男...
    Annie_66d0阅读 373评论 0 0
  • 《我的诗词》目录 百万家庭夜不眠,通宵达亘网波点。 一纸捷报雪霜剪,展翅飞翔新梦燃。
    青梅梦语阅读 802评论 8 28