踩坑
import someFnComponent from './someFnComponent'
const [fnComponent, setFnComponent] = useState();
setFnComponent(someFnComponent )
//此时引入的函数组件props会失效。当引用时组件的props一直会是undefined。
const myFnCom = () => {
return (
<someFnComponent />
)
}
useState 部分源码分析:
const HooksDispatcherOnMount: Dispatcher = {
/** 省略其它Hooks **/
useState: mountState,
};
// 所以调用useState()返回的就是HooksDispatcherOnMount.useState(),也就是mountState()
function mountState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
// 访问Hook链表的下一个节点,获取到新的Hook对象
const hook = mountWorkInProgressHook();
//如果入参是function则会调用,但是不提供参数
if (typeof initialState === 'function') {
initialState = initialState();
}
// 进行state的初始化工作
hook.memoizedState = hook.baseState = initialState;
//这个initialSatet也会出现函数组件不能获取props的问题
//下面是更新state的函数
function updateReducer(reducer, initialArg, init) {
// 获取初始化时的 hook
const hook = updateWorkInProgressHook();
const queue = hook.queue;
// 开始渲染更新
if (numberOfReRenders > 0) {
const dispatch = queue.dispatch;
if (renderPhaseUpdates !== null) {
// 获取Hook对象上的 queue,内部存有本次更新的一系列数据
const firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
if (firstRenderPhaseUpdate !== undefined) {
renderPhaseUpdates.delete(queue);
let newState = hook.memoizedState;
let update = firstRenderPhaseUpdate;
// 获取更新后的state
do {
const action = update.action;
// 此时的reducer是basicStateReducer,直接返回action的值
newState = reducer(newState, action);
update = update.next;
} while (update !== null);
// 对 更新hook.memoized
hook.memoizedState = newState;
// 返回新的 state,及更新 hook 的 dispatch 方法
return [newState, dispatch];
}
}
}
// 对于useState触发的update action来说,basicStateReducer就是直接返回action(state)的值
这样也会造成props的丢失
function basicStateReducer<S>(state: S, action: BasicStateAction<S>): S {
return typeof action === 'function' ? action(state) : action;
}
问题就出在了这里,如果传入的参数是函数,则会赋值,且提供state作为参数。
此时函数组件被传入当作普通函数。
然后赋值给newState
这时候如果把这个新的state当作函数组件使用,就会出现props丢失的问题。