React DOM 表单操作
一、作用
二、导出的常量
1. 未挂起
export const NotPending: FormStatus = __DEV__
? Object.freeze(sharedNotPendingObject)
: sharedNotPendingObject;
三、使用表单上一次提交状态
export function useFormStatus(): FormStatus {
const dispatcher = resolveDispatcher();
return dispatcher.useHostTransitionStatus();
}
四、使用表单状态
信息
官方推出了新的 Hook useActionState 来代替 useFormState。
用于描述一个可以根据某个表单动作的结果更新 state 的 Hook。
export function useFormState<S, P>(
action: (Awaited<S>, P) => S,
initialState: Awaited<S>,
permalink?: string,
): [Awaited<S>, (P) => void, boolean] {
const dispatcher = resolveDispatcher();
return dispatcher.useFormState(action, initialState, permalink);
}
五、请求表单重置
备注
ReactDOMSharedInternals()由 ReactDOMSharedInternals 实现
export function requestFormReset(form: HTMLFormElement) {
// ReactDOM当前调度器
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */
.r(/* requestFormReset */ form); // 请求表单重置
}
六、常量
1. 共享非待处理对象
// Since the "not pending" value is always the same, we can reuse the
// same object across all transitions.
//
// 由于“非待处理”值始终相同,我们可以在所有转换中重复使用同一个对象。
const sharedNotPendingObject: FormStatusNotPending = {
pending: false,
data: null,
method: null,
action: null,
};
// 表单状态非待处理
type FormStatusNotPending = {
pending: false;
data: null;
method: null;
action: null;
};
// 表单状态未待处理表单状态待处理
type FormStatusPending = {
pending: true;
data: FormData;
method: string;
action: string | ((formData: FormData) => void | Promise<void>) | null;
};
// 表单状态
export type FormStatus = FormStatusPending | FormStatusNotPending;
七、工具
1. 解析调度器
备注
ReactSharedInternals()由 ReactSharedInternals 实现
function resolveDispatcher() {
// Copied from react/src/ReactHooks.js. It's the same thing but in a
// different package.
// 从 react/src/ReactHooks.js 复制。它是相同的东西,但在不同的包中。
const dispatcher = ReactSharedInternals.H;
if (__DEV__) {
if (dispatcher === null) {
console.error(
'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://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.',
);
}
}
// Will result in a null access error if accessed outside render phase. We
// intentionally don't throw our own error because this is in a hot path.
// Also helps ensure this is inlined.
// 如果在渲染阶段之外访问,将导致 null 访问错误。我们故意不抛出自己的错误,因为这是热路径。
// 也有助于确保它被内联。
return dispatcher as any as Dispatcher;
}