博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React-Simple-Form轮子第一版释出
阅读量:5893 次
发布时间:2019-06-19

本文共 5341 字,大约阅读时间需要 17 分钟。

嗯,可能也是最后一版。。。哈哈~~~只是写着玩

简化版的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, key)=>{        let value = ['radio', '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 
; } } return Form; }}

用例:

index.js

import 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 (      
{ this.instance=instance; }} initialValues={
{ name: true }}/>
) }}

form.js

import 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 (      
) }}

用法:

@reactForm(options)

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}

Component 接受一个initialValues参数。和上面的initialValues作用一样,相同的key会覆盖option.initialValues中的值

API

  • handleSubmit, 写在formonSubmit事件中。

onSubmit={handleSumit}或者onSubmit={handleSubmit(fn)}fn会在form提交的时候调用,形参为form中的数据

  • fields,和redux-form一样。参考上面的例子

  • getValues 获取所有的数据

  • getTouchedValues 获取所有改变过(onChange)的数据

转载地址:http://axisx.baihongyu.com/

你可能感兴趣的文章
java的深拷贝与浅拷贝
查看>>
程序员如何提高工作效率
查看>>
数据库水平切分(其他应用)
查看>>
easyui 将已经是 textbox 的输入框改成时间框
查看>>
python基础学习整理——字典
查看>>
promise
查看>>
如何使用ABSL代码调用Web service
查看>>
将Java应用部署到SAP云平台neo环境的两种方式
查看>>
SAP CRM和C4C的客户主数据修改历史记录查询
查看>>
如何在CRM WebClient UI里使用HANA Live Report
查看>>
树莓派终端安装FTP服务器
查看>>
如何向妻子解释设计模式
查看>>
centos7关闭防火墙
查看>>
操作系统实验报告
查看>>
上传图片
查看>>
Codevs2018 反病毒软件
查看>>
nginx启动脚本
查看>>
三级菜单
查看>>
异常:java.io.IOException: Too many open files:
查看>>
POJ 1611 The Suspects (并查集求数量)
查看>>