React源码解析
<p>一直在用react进行编码,下面来看一下react框架的源码,了解一下react框架的思路。</p><p>首先,看下packages/react文件夹下的代码,也就是React</p>
<p>通过packages/react/index.js,可以大致了解到有哪些常用的react api</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
act as unstable_act,
Children,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
SuspenseList,
cloneElement,
createContext,
createElement,
createFactory,
createMutableSource,
createRef,
createServerContext,
experimental_use,
forwardRef,
isValidElement,
lazy,
memo,
............
useId,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useEffect,
useImperativeHandle,
useInsertionEffect,
useLayoutEffect,
useMemo,
useMutableSource,
useSyncExternalStore,
useReducer,
useRef,
useState,
useTransition,
version,
} from </span>'./src/React';</pre>
</div>
<p>这边把自己常用的来进行分析讲解</p>
<p><span style="font-size: 16px"><strong>1. Component, pureComponent</strong></span></p>
<p>在进行类组件编写时,第一步就是进行该构造函数的继承</p>
<p> question: 什么时候要使用pureComponent? pureComponent有什么注意事项吗?</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">class TestCom extends React.Component
or
class TestCom extends React.PureComponent</span></pre>
</div>
<p>源码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">import {Component, PureComponent} from './ReactBaseClasses';</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Component(props, context, updater) {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.props =<span style="color: rgba(0, 0, 0, 1)"> props;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.context =<span style="color: rgba(0, 0, 0, 1)"> context;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.refs = emptyObject; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> {}</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> We initialize the default updater but the real one gets injected by the</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> renderer.</span>
<span style="color: rgba(0, 0, 255, 1)">this</span>.updater = updater ||<span style="color: rgba(0, 0, 0, 1)"> ReactNoopUpdateQueue;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">上面代码中,constructor()、toString()、toValue()这三个方法,其实都是定义在Component.prototype上面。</span>
<span style="color: rgba(0, 128, 0, 1)">//eg:</span><span style="color: rgba(0, 128, 0, 1)"> 在继承时,使用class引入,写法更加清晰</span>
<span style="color: rgba(0, 0, 0, 1)">class TestCom extends React.Component {
constructor (props) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 构造方法,没写的时候默认执行</span>
<span style="color: rgba(0, 0, 0, 1)"> super(props)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 调用父类的constructor(props)</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> constructor默认返回实例对象(this)</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在super之后才能使用this,例如this.state</span>
<span style="color: rgba(0, 0, 0, 1)">}
}</span></pre>
</div>
<pre><span>ReactNoopUpdateQueue是一个对象,上面有一些方法,是用于对一些错误信息得提示<br></span></pre>
<div class="cnblogs_code">
<pre>ReactNoopUpdateQueue =<span style="color: rgba(0, 0, 0, 1)"> {
isMounted: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(publicInstance) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
},
enqueueForceUpdate: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(publicInstance, callback,
callerName) {
warnNoop(publicInstance, </span>'forceUpdate'<span style="color: rgba(0, 0, 0, 1)">);
},
enqueueReplaceState: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){},
enqueueSetState: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {}
}
warnNoop() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 进行一些错误信息得提示</span>
const constructor =<span style="color: rgba(0, 0, 0, 1)"> publicInstance.constructor;
const componentName </span>=<span style="color: rgba(0, 0, 0, 1)">
(constructor </span>&& (constructor.displayName || constructor.name)) ||
'ReactClass'<span style="color: rgba(0, 0, 0, 1)">;
const warningKey </span>=<span style="color: rgba(0, 0, 0, 1)"> `${componentName}.${callerName}`;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (didWarnStateUpdateForUnmountedComponent) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
console.error(..........);
didWarnStateUpdateForUnmountedComponent </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p> </p>
<pre><span> </span></pre>
<p> </p>
<pre><span> </span></pre>
<p><span style="color: rgba(255, 0, 0, 1)">在Component原型上绑定了setState, forceUpdate方法</span></p>
<p><strong><span style="color: rgba(0, 0, 0, 1)">setState</span></strong></p>
<p> </p>
<div class="cnblogs_code">
<pre>Component.prototype.setState = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(partialState, callback) {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.updater.enqueueSetState(<span style="color: rgba(0, 0, 255, 1)">this</span>, partialState, callback, 'setState'<span style="color: rgba(0, 0, 0, 1)">);
};
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> this.setState({name: 'test'})</span>
<span style="color: rgba(0, 0, 0, 1)">
enqueueSetState: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(
publicInstance,
partialState, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 需要更新得state -> name: 'test'</span>
<span style="color: rgba(0, 0, 0, 1)"> callback,
callerName,
) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这里没有对partialState进行更新</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 源码注释也进行了说明:不能保证对 `setState` 的调用会同步运行,因为它们最终可能会被批量处理,因为您的函数可能在 receiveProps 之后调用</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> shouldComponentUpdate,这个新的 state、props 和 context 还不会分配给这个</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> ps: 但是并不是这里对于new state更新</span>
warnNoop(publicInstance, 'setState'<span style="color: rgba(0, 0, 0, 1)">);
},
setState(updater[, callback])
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">setState() 的第二个参数为可选的回调函数,它将在 setState 完成合并并重新渲染组件后执行</span>
<span style="color: rgba(0, 0, 255, 1)">this</span>.setState((state, props) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> state,props接受得都保证为最新</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> {counter: state.counter +<span style="color: rgba(0, 0, 0, 1)"> props.step};
});</span></pre>
</div>
<p><span style="font-size: 14px">上述对于setState的代码感觉并没有发现对于机制的执行,全局搜索时,发现有</span>enqueueSetState,是什么时候执行的,起的什么作用呢</p>
<p> </p>
<div class="cnblogs_code">
<pre>const classComponentUpdater =<span style="color: rgba(0, 0, 0, 1)"> {
enqueueSetState(inst, payload, callback) {
const fiber </span>= getInstance(inst); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> key._reactInternals</span>
const eventTime = requestEventTime(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取时间</span>
const lane =<span style="color: rgba(0, 0, 0, 1)"> requestUpdateLane(fiber);
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> requestUpdateLane() 事件队列</span>
export <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> requestUpdateLane(fiber: Fiber): Lane {
}</span></pre>
</div>
<p> </p>
<p> </p>
<p><strong>forceUpdate:对于组件的强制更新</strong></p>
<div class="cnblogs_code">
<pre>Component.prototype.forceUpdate = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(callback) {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.updater.enqueueForceUpdate(<span style="color: rgba(0, 0, 255, 1)">this</span>, callback, 'forceUpdate'<span style="color: rgba(0, 0, 0, 1)">);
};
enqueueForceUpdate: </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(publicInstance, callback, callerName) {
warnNoop(publicInstance, </span>'forceUpdate'<span style="color: rgba(0, 0, 0, 1)">);
},
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 当状态更新时,但未调用setState, 这不会调用`shouldComponentUpdate`,但会调用`componentWillUpdate` 和 `componentDidUpdate`</span></pre>
</div>
<p> question : 重点:这里并没有进行一些其他的操作,只是调用warnNoop,是怎么进行了功能的实现?</p>
<p>-----------------------------------------------------------------------------待回答----------------------------------------------</p>
<p> </p>
<p><strong><span style="color: rgba(0, 0, 0, 1); font-size: 16px">PureComponent</span></strong></p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> PureComponent(props, context, updater) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 与Component相同</span>
<span style="color: rgba(0, 0, 0, 1)">}
const pureComponentPrototype </span>= (PureComponent.prototype = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ComponentDummy());
pureComponentPrototype.constructor </span>=<span style="color: rgba(0, 0, 0, 1)"> PureComponent;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将Component的原型赋值给PureComponent,并且将其constructor属性更改为PureComponent </span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 避免这些方法的额外原型跳转</span>
<span style="color: rgba(0, 0, 0, 1)">assign(pureComponentPrototype, Component.prototype);
pureComponentPrototype.isPureReactComponent </span>= <span style="color: rgba(0, 0, 255, 1)">true</span>;</pre>
</div>
<p> </p>
<p>Component与PureComponent类基本相同,唯一的区别是PureComponent上多了一个标识isPureReactComponent</p>
<p>// react-reconciler</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> checkShouldComponentUpdate() </span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 检查组件是否需要更新,</span>
<span style="color: rgba(0, 0, 0, 1)">checkShouldComponentUpdate(.....) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctor.prototype &&<span style="color: rgba(0, 0, 0, 1)"> ctor.prototype.isPureReactComponent) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对于PureComponent而言,当state和props未更新时,组件不重新渲染</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span>!shallowEqual(oldProps, newProps) || !<span style="color: rgba(0, 0, 0, 1)">shallowEqual(oldState, newState)
);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
} </span></pre>
</div>
<p>但是在使用PureComponent 过程中,避免出现props中引用类型,虽然props发生变化但地址未变,导致虽然props更新但组件未更新的bug.</p>
<div> </div>
<div><span style="font-size: 16px"><strong>2.Fragment</strong></span></div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">export { REACT_FRAGMENT_TYPE as Fragment}
export const REACT_FRAGMENT_TYPE </span>= Symbol.<span style="color: rgba(0, 0, 255, 1)">for</span>('react.fragment'); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Symbol(react.fragment) 只是一个占位符?</span></pre>
</div>
<p> </p>
</div>
<div><span style="font-size: 16px"><strong>3. createContext</strong></span></div>
<div><span style="font-size: 16px"><span style="font-size: 14px">context提供了一种无需为每层组件手动添加props,就能在组件树间进行数据传递的方法</span></span></div>
<div>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">function</span> createContext<T>(defaultValue: T): ReactContext<T><span style="color: rgba(0, 0, 0, 1)"> {
const context: ReactContext</span><T> =<span style="color: rgba(0, 0, 0, 1)"> {
$$</span><span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)">: REACT_CONTEXT_TYPE,
_currentValue: defaultValue,
_currentValue2: defaultValue,
_threadCount: </span>0<span style="color: rgba(0, 0, 0, 1)">,
Provider: (</span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">: any),
Consumer: (</span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">: any),
_defaultValue: (</span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">: any),
_globalName: (</span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">: any),
};
context.Provider </span>=<span style="color: rgba(0, 0, 0, 1)"> {
$$</span><span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)">: REACT_PROVIDER_TYPE,
_context: context,
};
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> context;
}</span></pre>
</div>
<p><span style="font-size: 16px"><strong>4.createRef</strong></span></p>
<p><span style="font-size: 14px"><code class="gatsby-code-text">React.createRef</code> 创建一个能够通过 ref 属性附加到 React 元素的 ref。</span></p>
</div>
<div>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> createRef(): RefObject {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个具有current:null 属性的对象</span>
const refObject =<span style="color: rgba(0, 0, 0, 1)"> {
current: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
};
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (__DEV__) {
Object.seal(refObject);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> refObject;
}</span></pre>
</div>
<p><span style="font-size: 16px"><strong>5.memo</strong></span></p>
<p><span style="font-size: 14px">React.memo为高阶组件</span></p>
<p><span style="font-size: 14px">你的组件在相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 <code class="gatsby-code-text">React.memo</code> 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现</span></p>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">function</span> memo<Props><span style="color: rgba(0, 0, 0, 1)">(
type: React$ElementType,
compare</span>?: (oldProps: Props, newProps: Props) => <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)">,
) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> $$typeof属性是为了虚拟dom的安全性</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用Symbol标记每个React元素,减少xss攻击</span>
$$<span style="color: rgba(0, 0, 255, 1)">typeof</span>: REACT_MEMO_TYPE, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Symbol.for('react.memo');</span>
<span style="color: rgba(0, 0, 0, 1)"> type,
compare: compare </span>=== undefined ? <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)"> : compare,
};
}</span></pre>
</div>
<p> </p>
<p><span style="font-size: 16px"><strong>6. useCallback与useMemo</strong></span></p>
<p><code class="gatsby-code-text">useCallback(fn, deps)</code> 相当于 <code class="gatsby-code-text">useMemo(() => fn, deps)</code>。</p>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">function</span> useCallback<T><span style="color: rgba(0, 0, 0, 1)">(
callback: T,
deps: Array</span><mixed> | <span style="color: rgba(0, 0, 255, 1)">void</span> | <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
): T {
const dispatcher </span>=<span style="color: rgba(0, 0, 0, 1)"> resolveDispatcher();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> dispatcher.useCallback(callback, deps);
}
export </span><span style="color: rgba(0, 0, 255, 1)">function</span> useMemo<T><span style="color: rgba(0, 0, 0, 1)">(
create: () </span>=><span style="color: rgba(0, 0, 0, 1)"> T,
deps: Array</span><mixed> | <span style="color: rgba(0, 0, 255, 1)">void</span> | <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
): T {
const dispatcher </span>=<span style="color: rgba(0, 0, 0, 1)"> resolveDispatcher();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> dispatcher.useMemo(create, deps);
}
const memoizedCallback </span>=<span style="color: rgba(0, 0, 0, 1)"> useCallback(
() </span>=><span style="color: rgba(0, 0, 0, 1)"> {
doSomething(a, b);
},
,
);</span></pre>
</div>
<p> </p>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">function</span> useCallback<T><span style="color: rgba(0, 0, 0, 1)">(
callback: T,
deps: Array</span><mixed> | <span style="color: rgba(0, 0, 255, 1)">void</span> | <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
): T {
const dispatcher </span>=<span style="color: rgba(0, 0, 0, 1)"> resolveDispatcher();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> dispatcher.useCallback(callback, deps);
}
const memoizedCallback </span>=<span style="color: rgba(0, 0, 0, 1)"> useCallback(
() </span>=><span style="color: rgba(0, 0, 0, 1)"> {
doSomething(a, b);
},
,
);</span></pre>
</div>
<p> </p>
<p>7.createElement</p>
<p>react中<code>JSX</code>在编译时会被<code>Babel</code>编译为<code>React.createElement</code>方法</p>
<p>即使文件中没使用其他引用,在文件开头也需要引入 import React from 'react'</p>
<p>来看一下相关createElement的源码</p>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> createElement(type, config, children) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> type-> 元素类型 config -> 元素配置(一些类名等) children -> 子元素(该元素下的子元素)</span>
<span style="color: rgba(0, 0, 0, 1)">let propName;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Reserved names are extracted</span>
const props =<span style="color: rgba(0, 0, 0, 1)"> {};
let key </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
let ref </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
let self </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
let source </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (config != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将config处理后赋值给props</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ..........</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 子对象可以是多个参数,它们被转移到新分配的props对象上。</span>
const childrenLength = arguments.length - 2<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (childrenLength === 1<span style="color: rgba(0, 0, 0, 1)">) {
props.children </span>=<span style="color: rgba(0, 0, 0, 1)"> children;
} </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (childrenLength > 1<span style="color: rgba(0, 0, 0, 1)">) {
const childArray </span>=<span style="color: rgba(0, 0, 0, 1)"> Array(childrenLength);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i < childrenLength; i++<span style="color: rgba(0, 0, 0, 1)">) {
childArray </span>= arguments;
}
props.children </span>=<span style="color: rgba(0, 0, 0, 1)"> childArray;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Resolve default props</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (type &&<span style="color: rgba(0, 0, 0, 1)"> type.defaultProps) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ............</span>
<span style="color: rgba(0, 0, 0, 1)">}
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}</span></pre>
</div>
<p> </p>
<p> 看了一下,很多地方还是没有真正的理解,等后面再读一遍的时候再进行整理补充吧</p>
<p>待续</p>
<p> </p>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/best-mll/p/16732274.html
頁:
[1]