当前位置: 首页 > news >正文

郑州大型网站开发公司推广网页

郑州大型网站开发公司,推广网页,用java做中小企业网站多,wordpress 入门Hooks 1 )概述 Hooks 在 React16.7版本出现的新功能Hooks 改变了整体应用开发的模式,同时开发体验会和以前会变得不一样Hooks 让函数组件具有类组件的能力 在 function component 里面没有this无法保存 state通过 Hooks可以让 function component 代替…

Hooks

1 )概述

  • Hooks 在 React16.7版本出现的新功能
  • Hooks 改变了整体应用开发的模式,同时开发体验会和以前会变得不一样
  • Hooks 让函数组件具有类组件的能力
    • 在 function component 里面没有this无法保存 state
    • 通过 Hooks可以让 function component 代替 class component
    • Hooks 让函数组件变得更强大

2 )用例演示

import React, { useState, useEffect } from 'react'export default () => {const [name, setName] = useState('Wang')useEffect(() => {console.log('component update')return () => {console.log('unbind')}}, [])return (<><p>My Name is: {name}</p><input type="text" value={name} onChange={e => setName(e.target.value)} /></>)
}
  • 这里声明了一个functional component ,在以前对比class component它缺少的是什么
    • 缺少就是this对象,它没有this对象,那么它就不能有 this.state
    • 它就具有包含自己本身的状态的这么一个功能
    • 它没有生命周期方法
  • 在这里面我们使用了hooks来给我们的组件去存储了 state
    • 使用 useState 传入了一个默认值是 Wang
    • 然后它返回一个数组,这是一个数组的解构
    • 这个数组第一项是state的对应的这个变量
    • 第二项是让我们去改变这个state的方法
    • 这就是我们通过useState返回给我们的唯一的两个东西
  • 然后我们就可以在我们渲染的过程当中去使用这个state了,同样可以去修改这个state
    • 比如说我们绑定了这个input的 onchange 事件
    • 就是去修改这个state,就是我们的name
    • 输入的内容之后它的state就自动更新
    • 在下一次渲染的时候能够拿到 state
  • 这就是hooks,它给 function component 提供了class component 所具有的能力
    • 它的意义不仅仅是为了替代 class compoment
    • 是想要去帮助我们去拆分一些在组件内部的逻辑
    • 把他们提取出来,能够给更多的组件进行一个复用
    • 以前在class compoment 里面是很难去拆分这部分逻辑的
  • 还有一个是跟 class component 的最大区别,就是生命周期方法
    • 在function component 里面,使用hooks可以通过一个叫做useEffect的这个API
    • 这个东西呢我们就可以传入一个方法,这个方法里面
    • 比如说,随便写一句 component updated
    • 在hooks里面,他没有着重的去区分 mounted 和 updated
    • 它的理念是 mounted和updated 都是 updated
    • 每一次有组件内容更新的时候都会去调用我们传入的这个 effect 回调函数
  • 如果需要事件绑定什么的,之前在unmount的时候,去解除事件绑定,那这时怎么办
    • 很简单,看到上面 return一个方法,这个方法就是解除我们的绑定,这边叫做 unbind
    • 在目前这种情况下,每一次有更新的时候都会先执行unbind,然后再重新bind
    • 这是比较符合react更新的一个逻辑的,就是在它有任何更新的时候
    • 都会把之前的状态全部消除,然后返回新的状态
  • 当然这对于一些事件监听的绑定不是特别友好, 解决方案如下
    • 把它改造成行为,类似于 componentDidMount 和 componentWillUnmount
    • 直接在这个 useEffect 传入第二个参数,然后传一个空数组
    • 比如说传入一个props来进行一个它是否有变化的一个区分
    • 如果传一个空数组,它就没有东西区分,就代表着只要执行一次
    • 这样,在输入改变state时,就没有了,只再刷新后,才会执行一次
  • 同样,在跳出的时候打印输出了 unbind
  • 这就是我们使用 hooks 模拟生命周期方法的一个用法

3 ) 源码分析

这个要在 React 16.7 版本上来找,在 React.js 中可看到

import {useCallback,// ... 很多 khoos
} from './ReactHooks';

现在定位到 ReactHooks.js

/*** Copyright (c) Facebook, Inc. and its affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.** @flow*/import type {MutableSource,MutableSourceGetSnapshotFn,MutableSourceSubscribeFn,ReactContext,
} from 'shared/ReactTypes';
import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig';import invariant from 'shared/invariant';import ReactCurrentDispatcher from './ReactCurrentDispatcher';type BasicStateAction<S> = (S => S) | S;
type Dispatch<A> = A => void;function resolveDispatcher() {const dispatcher = ReactCurrentDispatcher.current;invariant(dispatcher !== null,'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +' one of the following reasons:\n' +'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +'2. You might be breaking the Rules of Hooks\n' +'3. You might have more than one copy of React in the same app\n' +'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',);return dispatcher;
}export function useContext<T>(Context: ReactContext<T>,unstable_observedBits: number | boolean | void,
): T {const dispatcher = resolveDispatcher();if (__DEV__) {if (unstable_observedBits !== undefined) {console.error('useContext() second argument is reserved for future ' +'use in React. Passing it is not supported. ' +'You passed: %s.%s',unstable_observedBits,typeof unstable_observedBits === 'number' && Array.isArray(arguments[2])? '\n\nDid you call array.map(useContext)? ' +'Calling Hooks inside a loop is not supported. ' +'Learn more at https://reactjs.org/link/rules-of-hooks': '',);}// TODO: add a more generic warning for invalid values.if ((Context: any)._context !== undefined) {const realContext = (Context: any)._context;// Don't deduplicate because this legitimately causes bugs// and nobody should be using this in existing code.if (realContext.Consumer === Context) {console.error('Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be ' +'removed in a future major release. Did you mean to call useContext(Context) instead?',);} else if (realContext.Provider === Context) {console.error('Calling useContext(Context.Provider) is not supported. ' +'Did you mean to call useContext(Context) instead?',);}}}return dispatcher.useContext(Context, unstable_observedBits);
}export function useState<S>(initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {const dispatcher = resolveDispatcher();return dispatcher.useState(initialState);
}export function useReducer<S, I, A>(reducer: (S, A) => S,initialArg: I,init?: I => S,
): [S, Dispatch<A>] {const dispatcher = resolveDispatcher();return dispatcher.useReducer(reducer, initialArg, init);
}export function useRef<T>(initialValue: T): {|current: T|} {const dispatcher = resolveDispatcher();return dispatcher.useRef(initialValue);
}export function useEffect(create: () => (() => void) | void,deps: Array<mixed> | void | null,
): void {const dispatcher = resolveDispatcher();return dispatcher.useEffect(create, deps);
}export function useLayoutEffect(create: () => (() => void) | void,deps: Array<mixed> | void | null,
): void {const dispatcher = resolveDispatcher();return dispatcher.useLayoutEffect(create, deps);
}export function useCallback<T>(callback: T,deps: Array<mixed> | void | null,
): T {const dispatcher = resolveDispatcher();return dispatcher.useCallback(callback, deps);
}export function useMemo<T>(create: () => T,deps: Array<mixed> | void | null,
): T {const dispatcher = resolveDispatcher();return dispatcher.useMemo(create, deps);
}export function useImperativeHandle<T>(ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,create: () => T,deps: Array<mixed> | void | null,
): void {const dispatcher = resolveDispatcher();return dispatcher.useImperativeHandle(ref, create, deps);
}export function useDebugValue<T>(value: T,formatterFn: ?(value: T) => mixed,
): void {if (__DEV__) {const dispatcher = resolveDispatcher();return dispatcher.useDebugValue(value, formatterFn);}
}export const emptyObject = {};export function useTransition(): [(() => void) => void, boolean] {const dispatcher = resolveDispatcher();return dispatcher.useTransition();
}export function useDeferredValue<T>(value: T): T {const dispatcher = resolveDispatcher();return dispatcher.useDeferredValue(value);
}export function useOpaqueIdentifier(): OpaqueIDType | void {const dispatcher = resolveDispatcher();return dispatcher.useOpaqueIdentifier();
}export function useMutableSource<Source, Snapshot>(source: MutableSource<Source>,getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,subscribe: MutableSourceSubscribeFn<Source, Snapshot>,
): Snapshot {const dispatcher = resolveDispatcher();return dispatcher.useMutableSource(source, getSnapshot, subscribe);
}
  • 定位到 useState

    export function useState<S>(initialState: (() => S) | S,
    ): [S, Dispatch<BasicStateAction<S>>] {const dispatcher = resolveDispatcher();return dispatcher.useState(initialState);
    }
    
    • 这边调用了一个 dispatcher.useState(initialState);
    • 这个dispatch等于 const dispatcher = resolveDispatcher();
  • 对应的再去找到这个 resolveDispatcher ,它是个function

    function resolveDispatcher() {const dispatcher = ReactCurrentOwner.currentDispatcher;invariant(dispatcher !== null,'Hooks can only be called inside the body of a function component.',);return dispatcher;
    }
    
    • 可看到是通过 ReactCurrentOwner.currentDispatcher 去获取的
    • 这个就要涉及到后续react-dom渲染的过程
    • 在我们使用阶段,是没有拿到任何真正节点的实例的。
    • 比如在我们创建了react element,我们传进去的是这个class component的类
    • 而不是它的一个new的一个实例,拿不到对应的东西
    • 只有在 react-dom 进行真正的渲染的过程当中,才会去为我们创建这个实例
    • 它这边提供了这个方法,在实际调用是要在我们的 react-dom进行渲染的时候
    • 它才会为我们这个 ReactCurrentOwner 去设置属性
  • ReactCurrentOwner 它是一个全局的类,定位一下

    /*** Copyright (c) Facebook, Inc. and its affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.** @flow*/import type {Fiber} from 'react-reconciler/src/ReactFiber';
    import typeof {Dispatcher} from 'react-reconciler/src/ReactFiberDispatcher';/*** Keeps track of the current owner.** The current owner is the component who should own any components that are* currently being constructed.*/
    const ReactCurrentOwner = {/*** @internal* @type {ReactComponent}*/current: (null: null | Fiber),currentDispatcher: (null: null | Dispatcher),
    };export default ReactCurrentOwner;
    
  • 我们可以看到 ReactCurrentOwner ,它就是一个对象,里面有两个属性

  • 一个是 current , 就是这个current就对应正在目前正在渲染的哪一个节点的一个实例

  • currentDispatcher 是实例对应的 dispatcher

  • 它一开始初始化的时候,是两个 null

  • 然后到后期每一个组件进行渲染的时候,它才会进行一个渲染

  • 就跟我们在class component里面看到的,它的 setState 调用的是 this.updateSetState

  • 在这里的 dispatch 也是从不同平台上面,它传入进来的一个东西,不是我们在react中定义的

  • 所以在react中我们可以看到的源码就非常的简单,就是这么一些相关的东西

  • 同理,useEffect和其他内容也基本是类似的,只不过它最终调用的方法会不一样

  • 比如说useReducer,那么它调用的是 dispatcher.useReducer

  • 它们最终都是调用 dispatcher 上面的方法

http://www.ritt.cn/news/9198.html

相关文章:

  • 国内优秀网站设计曲靖百度推广
  • 企业网络规划毕业设计seo怎么优化方法
  • 汉中党建网站作风建设全媒体运营师报名费多少钱
  • 知名企业网站建设搜索引擎优化结果
  • 网络做网站东莞seo推广公司
  • 网站框架代码营销模式有哪些 新型
  • 网站设计参考文献aso关键词优化计划
  • 做网站一定需要服务器吗百度平台交易
  • 网页空间是什么东莞seo网站优化排名
  • 不上此网站枉做男人今日的头条新闻
  • 网站开发什么语言好舆情视频
  • 广州网站建设制作免备案域名
  • 济南网站外包优秀网页设计作品
  • 新建的网站百度搜索不到日照seo公司
  • 教育机构招聘网站建设关键词排名优化易下拉霸屏
  • 怎么建设网站网页游戏湖南正规seo公司
  • 网站建设织梦怎么样谷歌seo推广服务
  • 新疆吐鲁番建设网站网络推广渠道公司
  • 北京东方广场网站搜索优化找哪家
  • 做网站-信科网络百度收录提交
  • wordpress不显示缩略图湛江百度seo公司
  • 温岭做网站公司市场调研报告1000字
  • 网站盈利的10种方式域名污染查询网站
  • 微网站建设万能搜索引擎入口
  • 做短租公寓民宿网站微信5000人接推广费用
  • 江西医疗网站建设东莞专业网站推广工具
  • 中国建筑集团有限公司排名seo文案范例
  • 网站做订购爱战网关键词工具
  • 重庆有哪些做网站 小程序的站长之家 seo查询
  • 安居客网站是用什么程序做的企业培训课程设计