React-Simple-Form轮子第一版释出
发布时间:2020-12-15 07:23:39 所属栏目:百科 来源:网络整理
导读:嗯,可能也是最后一版。。。哈哈~~~只是写着玩 简化版的 redux-form ,只是觉得不需要 redux-form 那么复杂的功能,也不想要和 redux 关联,而且希望有一个简单管理 form 的东西,所以就写了一个。肯定有很多不足,比如 checkbox/radio group 怎么管理。。。
嗯,可能也是最后一版。。。哈哈~~~只是写着玩 简化版的 import React from 'react'; export default function reactForm(options){ const { fields=[],initialValues={},validate,validateOnBlur,withRef } = options; return (Component)=>{ class Form extends React.Component { constructor(props) { super(props); this.initialValues = { ...initialValues,...props.initialValues }; this.state = this.getInitialFields(); this.touchedKeys = {}; } componentWillReceiveProps(nextProps){ if(this.props.initialValues != nextProps.initialValues) { this.initialValues = { ...initialValues,...nextProps.initialValues }; this.resetForm(); } } getInitialFields = ()=>{ return fields.reduce((prev,key)=>{ prev[key] = typeof this.initialValues[key] == "undefined" ? undefined : this.initialValues[key]; return prev; },{}) } resetForm = ()=>{ this.setState(this.getInitialFields()); } setInstance = (instance)=>{ this.instance = instance; } getInstance = ()=>{ if(withRef) return this.instance; console.error("Can not get instance when withRef is false"); } getValues = ()=>{ return fields.reduce((prev,key)=>{ prev[key] = this.state[key]; return prev; },{}); } getTouchedValues = ()=>{ let result = {}; for(let key in this.touchedKeys) { if(this.touchedKeys.hasOwnProperty(key)){ result[key] = this.state[key]; } } return result; } onFieldChange = (e,key)=>{ let value = ['radio','checkbox'].includes(e.target.type) ? e.target.checked : e.target.value; console.log(`trigger field change with ${key} ${value}`); this.setState({ [key]: value },()=>{ this.touchedKeys[key] = true; }); validate && validate(key,value); } onFieldBlur = (e,'checkbox'].includes(e.target.type) ? e.target.checked : e.target.value; validateOnBlur(key,value); } handleSubmit = (fn)=>{ if(typeof fn == "function") { return (e)=>{ e.preventDefault(); e.stopPropagation(); fn(this.getValues()); } } else { fn.preventDefault(); fn.stopPropagation(); } } buildFields = ()=>{ return fields.reduce((prev,key)=>{ let value = this.state[key]; let field = { onChange: (e)=>{ this.onFieldChange(e,key) } }; if(typeof value === "boolean") field.checked = value; else field.value = value; if(validateOnBlur) field.onBlur = (e)=>{ this.onFieldBlur(e,key) }; prev[key] = field; return prev; },{}) } buildProps = (props)=>{ let _props = { ...props }; _props.fields = this.buildFields(); _props.handleSubmit = this.handleSubmit; _props.getValues = this.getValues; _props.getTouchedValues = this.getTouchedValues; _props.resetForm = this.resetForm; if(withRef) { _props.ref = this.setInstance; } return _props; } render(){ let props = this.buildProps(this.props); return <Component { ...props } />; } } return Form; } } 用例: index.jsimport React from 'react'; import Form from './form'; export default class FormApp extends React.Component { constructor(props) { super(props); } onClick = ()=>{ console.log(this.instance.getTouchedValues()); } render(){ return ( <div> <Form ref={instance=>{ this.instance=instance; }} initialValues={{ name: true }}/> <button style={{ marginLeft: "200px" }} onClick={this.onClick}>Values</button> </div> ) } } form.jsimport React from 'react'; import reactForm from 'components/react-form'; function validate(key,value){ console.log(`validateOnBlur ${key} ${value}`); } @reactForm({ fields: ['name','bbb'],withRef: true,initialValues: { bbb: "bbbbbb" },validateOnBlur: validate }) export default class Form extends React.Component { constructor(props) { super(props); } onSubmit = (values)=>{ console.log(values); let { getTouchedValues } = this.props; console.log(getTouchedValues()); this.props.resetForm(); } render(){ let { fields: { name,bbb },handleSubmit } = this.props; return ( <form onSubmit={handleSubmit(this.onSubmit)} style={{ marginLeft: "200px" }}> <label> name: <input type="checkbox" name="name" value="123" {...name}/> </label> <label> bbb <input type="text" name="bbb" {...bbb}/> </label> <button type="submit">submit</button> </form> ) } } 用法:
options: { fields: ["field1","field2","field3","checkbox"...],// names of fields initialValues: { "field1":"value1","field2":"value2","checkbox":true },// the initial values of fields validate: fn,// the function will be called when onChange validateOnBlur: fn,// the function will be called when onBlur withRef: false // when this is true,you can get the inner component by using getInstance }
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |