ReactElement
key prop
// 尝试通过props获取key的时候,将会报错,不能把key作为prop来使用和看待function defineKeyPropWarningGetter(props, displayName) {const warnAboutAccessingKey = function() {if (__DEV__) {if (!specialPropKeyWarningShown) {specialPropKeyWarningShown = true;console.error('%s: `key` is not a prop. Trying to access it will result ' +'in `undefined` being returned. If you need to access the same ' +'value within the child component, you should pass it as a different ' +'prop. (https://reactjs.org/link/special-props)',displayName,);}}};// key prop getter覆盖warnAboutAccessingKey.isReactWarning = true;Object.defineProperty(props, 'key', {get: warnAboutAccessingKey,configurable: true,});}
同理 ref也是
function defineRefPropWarningGetter(props, displayName) {const warnAboutAccessingRef = function() {if (__DEV__) {if (!specialPropRefWarningShown) {specialPropRefWarningShown = true;console.error('%s: `ref` is not a prop. Trying to access it will result ' +'in `undefined` being returned. If you need to access the same ' +'value within the child component, you should pass it as a different ' +'prop. (https://reactjs.org/link/special-props)',displayName,);}}};warnAboutAccessingRef.isReactWarning = true;Object.defineProperty(props, 'ref', {get: warnAboutAccessingRef,configurable: true,});}
jsx方法
export function jsx(type, config, maybeKey) {let propName;// Reserved names are extractedconst props = {};let key = null;let ref = null;// maybeKey 备选keyif (maybeKey !== undefined) {key = '' + maybeKey;}// 校验keyif (hasValidKey(config)) {key = '' + config.key;}// ref校验 不能为stringif (hasValidRef(config)) {ref = config.ref;}// 开始处理propsfor (propName in config) {// config自身属性且不是保留字if (hasOwnProperty.call(config, propName) &&!RESERVED_PROPS.hasOwnProperty(propName)) {props[propName] = config[propName];}}// 保留字属性 自身属性 比如标签自己的属性 <a href="">if (type && type.defaultProps) {const defaultProps = type.defaultProps;for (propName in defaultProps) {if (props[propName] === undefined) {props[propName] = defaultProps[propName];}}}return ReactElement(type,key,ref,undefined,undefined,ReactCurrentOwner.current,props,);}
createElement
export function createElement(type, config, children) {let propName;// Reserved names are extractedconst props = {};let key = null;let ref = null;let self = null;let source = null;...const childrenLength = arguments.length - 2;// createElement(type, config, child)if (childrenLength === 1) {props.children = children;} else if (childrenLength > 1) {// createElement(type, config, child, child2, child3...)const childArray = Array(childrenLength);for (let i = 0; i < childrenLength; i++) {childArray[i] = arguments[i + 2];}if (__DEV__) {if (Object.freeze) {Object.freeze(childArray);}}props.children = childArray;}// Resolve default propsif (type && type.defaultProps) {const defaultProps = type.defaultProps;for (propName in defaultProps) {if (props[propName] === undefined) {props[propName] = defaultProps[propName];}}}if (__DEV__) {if (key || ref) {const displayName =typeof type === 'function'? type.displayName || type.name || 'Unknown': type;if (key) {defineKeyPropWarningGetter(props, displayName);}if (ref) {defineRefPropWarningGetter(props, displayName);}}}return ReactElement(type,key,ref,self,source,ReactCurrentOwner.current,props,);}
ReactContext
ReactLazy
懒加载组件兑现方法
function lazyInitializer<T>(payload: Payload<T>): T {// 未初始化过的组件if (payload._status === Uninitialized) {const ctor = payload._result;const thenable = ctor(); // 执行 获取promise// Transition to the next state.const pending: PendingPayload = (payload: any);pending._status = Pending; // pending状态pending._result = thenable;thenable.then(moduleObject => {// 预防其他地方已经执行了获取方法了if (payload._status === Pending) {const defaultExport = moduleObject.default;// Transition to the next state.const resolved: ResolvedPayload<T> = (payload: any);// 标记懒加载组件已resolvedresolved._status = Resolved;// 拿到了组件导出结果resolved._result = defaultExport;}},error => {if (payload._status === Pending) {// Transition to the next state.const rejected: RejectedPayload = (payload: any);rejected._status = Rejected;rejected._result = error;}},);}if (payload._status === Resolved) {return payload._result;} else {throw payload._result;}}
构造懒加载组件
export function lazy<T>(ctor: () => Thenable<{default: T, ...}>,): LazyComponent<T, Payload<T>> {const payload: Payload<T> = {_status: -1, // 未初始化状态_result: ctor, // 获取方法 一般是构造promise的方法};const lazyType: LazyComponent<T, Payload<T>> = {$$typeof: REACT_LAZY_TYPE,_payload: payload,_init: lazyInitializer,};return lazyType;}
ReactForwardRef
forwardRef
/*** 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.*/import {REACT_FORWARD_REF_TYPE, REACT_MEMO_TYPE} from 'shared/ReactSymbols';export function forwardRef<Props, ElementType: React$ElementType>(render: (props: Props, ref: React$Ref<ElementType>) => React$Node,) {if (__DEV__) {if (render != null && render.$$typeof === REACT_MEMO_TYPE) {console.error('forwardRef requires a render function but received a `memo` ' +'component. Instead of forwardRef(memo(...)), use ' +'memo(forwardRef(...)).',);} else if (typeof render !== 'function') {console.error('forwardRef requires a render function but was given %s.',render === null ? 'null' : typeof render,);} else {if (render.length !== 0 && render.length !== 2) {console.error('forwardRef render functions accept exactly two parameters: props and ref. %s',render.length === 1? 'Did you forget to use the ref parameter?': 'Any additional parameter will be undefined.',);}}if (render != null) {if (render.defaultProps != null || render.propTypes != null) {console.error('forwardRef render functions do not support propTypes or defaultProps. ' +'Did you accidentally pass a React component?',);}}}const elementType = {$$typeof: REACT_FORWARD_REF_TYPE,render,};if (__DEV__) {let ownName;Object.defineProperty(elementType, 'displayName', {enumerable: false,configurable: true,get: function() {return ownName;},set: function(name) {ownName = name;if (render.displayName == null) {render.displayName = name;}},});}return elementType;}
ReactMemo
memo
纯组件 只根据props,context等引发更新或者通过compare提供更新依据
export function memo<Props>(type: React$ElementType,compare?: (oldProps: Props, newProps: Props) => boolean,) {const elementType = {$$typeof: REACT_MEMO_TYPE,type,compare: compare === undefined ? null : compare,};return elementType;}
ReactHooks
function resolveDispatcher() {// 也就是引用current做事情const dispatcher = ReactCurrentDispatcher.current;return ((dispatcher: any): Dispatcher);}export function useContext<T>(Context: ReactContext<T>,unstable_observedBits: number | boolean | void,): T {const dispatcher = resolveDispatcher();if ((Context: any)._context !== undefined) {const realContext = (Context: any)._context;}}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);}export function useCacheRefresh(): <T>(?() => T, ?T) => void {const dispatcher = resolveDispatcher();// $FlowFixMe This is unstable, thus optionalreturn dispatcher.useCacheRefresh();}
