React-Hooks处理表单

  • 首先,在表单中使用React组件有
    • 受控组件
    • 非受控组件
function MyForm() {

    const [value, setValue] = useState('')

    const handleChange = (evt) => {

        setValue(evt.target.value)

    }

    return <input value={value} onChange={this.handleChange} />

}

受控组件,一个表单组件的状态完全由React管控,但是频繁的更新状态,可能会产生性能问题

function MyForm() {

    const inputRef = useRef()

    const handleSubmit = (evt) => {

        // 使用prevetnDefault防止页面被刷新

        evt.preventDefault()

        alert(inputRef.current.value)

    }
   
    return (

        <form onSubmit={handleSubmit}>

            <label>

                Name:

                <input ref={inputRef} />

            </label>

            <input type="submit" value="Submit" />

        </form>

    )

}

非受控组件,表单元素的值不是由父组件决定的,而是完全内部的状态。

可以看到,通过非受控组件的方式,input的输入过程对整个组件状态没有任何影响,自然也不会导致组件的重新渲染。

使用Hooks简化表单处理

之前,对于受控组件,遵循下面两个步骤:
  • 设置一个State用于绑定到表单元素的value
  • 监听表单元素的onChange事件,将表单值同步到State中

即,维护表单组件的状态逻辑,核心在于三个部分:

  • 字段的名字
  • 绑定value值
  • 处理onChange事件

既然对于每个表单元素的处理逻辑都是一样的,我们可以用hooks来实现逻辑的复用

  • 主要思想:用hooks去维护整个表单,根本名字去取值或者修改
    基本实现:
const useForm = (initialValues = {}) => {

    // 设置整个form的状态values

    const [values, setValues] = useState(initialValues)

    const setFieldValue = useCallback((name,value) => {

        setValues((value) => return {

            ...values,

            [name]: value

        })

    }, [])

    return { values, setFieldValue }

}

使用时:

// ...

const [values, setFieldValues] = useForm()

// ...

<input value={values.name || null} onChange={setFieldValues('name',evt.target.value)} />

<input value={values.email || null} onChange={setFieldValues('email', evt.target.value)} />

基本上一些开源的表单方案都是基于这么一个核心的原理:把表单的状态管理单独提取出来,成为一个可重用的Hook。

  • 处理表单验证
    • 增加一个表单处理的必备逻辑:表单验证

同样遵循状态驱动这个原则:

  • 首先:如何定义这样的错误状态
  • 其次:如何去设置这个错误状态

下面,为已有的useForm这个Hook增加验证的API接口:

// 提供一个validators对象提供针对某个字段的验证函数

const useForm = (initialValues = {}, validators) => {

    const [values,setValues] = useState(initialValues)

    // 定义了 errors 状态

    const [errors, setErrors] = useState({})

    const setFieldValue = useCallback((name, value) => {

        setValues(({

            ...values,

            [name]: value

        }))

        // 调用验证函数验证用户输入

        if (validators[name]) {

            const errMsg = validators[name](value)

            setErrors((errors) => ({

                ...errors,

                [name]: errMsg || null

            }))

        }

    },[validators])

    return { values, errors, setFieldValue }

}

044113B0-3E30-47CD-8B23-BE4613207DD9.png

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值