支持多级绑定。
参考:
依赖
yarn add immer lodash
form-state.js
import React from "react";import produce from "immer"import set from "lodash/set";import has from "lodash/has";// eslint-disable-next-line consistent-returnconst enhancedReducer = (state, updateArg) => {// check if the type of update argument is a callback functionif (updateArg.constructor === Function) {return {...state, ...updateArg(state)};}// if the type of update argument is an objectif (updateArg.constructor === Object) {// does the update object have _path and _value as it's keys// if yes then use them to update deep object valuesif (has(updateArg, "_path") && has(updateArg, "_value")) {const {_path, _value} = updateArg;return produce(state, draft => {set(draft, _path, _value);});}return {...state, ...updateArg};}};const useFormState = initialState => {const [state, updateState] = React.useReducer(enhancedReducer, initialState);const updateForm = React.useCallback(({target: {value, name, type}}) => {const updatePath = name.split(".");// if the input is a checkbox then use callback function to update// the toggle state based on previous stateif (type === "checkbox") {updateState(prevState => ({[name]: !prevState[name]}));return;}// if we have to update the root level nodes in the formif (updatePath.length === 1) {const [key] = updatePath;updateState({[key]: value});}// if we have to update nested nodes in the form object// use _path and _value to update them.if (updatePath.length === 2) {updateState({_path: updatePath,_value: value});}}, []);return [state, updateState,updateForm];};export default useFormState;
使用
import useFormState from "./form-state";const initialState = {fname: "",lname: "",email: "",message: ""};const [state, updateState,updateForm] = useFormState(initState);state 表示表单updateState 用来手动更新stateupdateForm 自动双向绑定
绑定示例:

