当前位置:

react hooks 实现受控组件双向绑定

访客 2024-04-24 539 0

前言

了解或会Vue的朋友都知道,在Vue中我们可以通过v-model实现受控组件的数据双向绑定,而在React中则需要通过valueonChange实现数据的双向绑定,单个还可以接受,如多个呢。

看个例子。

const[nickName,setNickName]=useState('')const[age,setAge]=useState(null)consthandleNickNameChange=useCallback((value)=>{setNickName(value)},[])consthandleAgeChange=useCallback((value)=>{setAge(value)},[])return(<><Inputvalue={nickName}onChange={handleNickNameChange}/><Inputvalue={age}onChange={handleAgeChange}/></>)

根据上面得出结论,如果一个组件内有多个受控组件,那将会向上面一样写很多个。我们能不能封装一下只需要声明变量,不需要声明set方法呢。答案是OK的,可以看下面。

Tips:input的type的值为file时为非受控组件,原因是因为type为file时的value处于可读状态。

说明

我这里使用的是Reactts,使用js的话需要删除变量后面的类型声明。

withModel

我这里封装的方法组件为withModel,你们可以根据自身命名。

//withModel.tsximportReact,{forwardRef,useMemo,useCallback,useEffect}from'react'//双向绑定工具方法constwithModel=(Component:any)=>forwardRef((props,outerRef)=>{constp={models:[],name:'',value:'',onChange:(event:any)=>{},...props,}const{models=[],name,value,onChange,...other}=p;const[modelValue,setModelValue]=useMemo(()=>models,[models])consthandleChange=useCallback((event:any)=>{if(setModelValue){constsetValue=setModelValueasFunction;setValue(event.target.value)}if(typeofonChange==='function')onChange(event)},[onChange])return(<Component{...other}ref={outerRef}name={name}value={modelValue!==undefined?modelValue:value}onChange={handleChange}/>)})exportdefaultwithModel

input.tsx

//input.tsximportReact,{forwardRef}from"react";importwithModelfrom'../utils/withModel'typeinputProps=React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>,HTMLInputElement>constComponent=forwardRef<HTMLInputElement,inputProps>((props,outerRef)=>{constp={...props};let{type}=props;if(!type)type='text';letelement=<inputref={outerRef}{...props}/>return(<>{!['checkbox','file','radio'].includes(type)&&element}</>)})Component.displayName='Input'exportdefaultwithModel(Component);

页面使用

//页面使用importReact,{useState}from"react";importInputfrom"./Input"exportdefault()=>{constdata=useState('我是输入的内容')return(<><Inputmodels={data}placeholder="请输入内容"/>{/**/}<p>{`我是输入的内容:${data[0]}`}</p></>)}

总结

原理:使用forwardRef将当前受控组件的ref引用进行传递,通过withModel组件方法进行修改。

如有不足还请各位指点。

搞定收工。

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~