设计思路
form3: 点击submit的时候肯定要拿到所有的状态值,存到父级(form)这个上面。缺点:一个更新所有input都要更新 form4: 该谁更新谁更新。第三方的状态管理库store,想要更新就订阅一下
搭架子
Form
对form来说只要将子组件渲染出来就行
import React from 'react'
export default function Form(props) {
const {children} = props
return (
<form>
{children}
</form>
)
}
Field
对form来说只要将子组件渲染出来就行
import React, { Component } from 'react'
export default class Field extends Component {
render() {
const {children} = this.props
return children
}
}
input
import React, { Component } from 'react'
const Input = (props) => {
return <input {...props}/>
}
export default class CustomizeInput extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
const { value = "", ...otherProps } = this.props
return (
<div>
<Input style={{outline:'none'}} value={value} {...otherProps}></Input>
</div>
)
}
}
useForm
import React from 'react'
export default function useForm() {
return []
}
index.js
import _Form from "./Form";
import Field from "./Field";
import useForm from "./useForm";
const Form = _Form
Form.Field = Field
Form.useForm = useForm
export {
Field,
useForm
}
export default Form
Filed
显示的children不是受控组件 重新定义value
const returnChildNode = React.cloneElement(children, this.getControlled())
getControlled = () => {
return {
value: 'omg',
onChange: (e) => {
const newvalue = e.target.value
console.log('newvalue',newvalue);
}
}
}
useForm
value 应该是form表单的状态值,可以用第三方状态管理库(FormStore)来控制value,用get获取最新状态,set设置 FormStore有了,只要组件没有卸载,那就不变化。该存在哪里?
- 函数组件内部因为多次更新会导致多次更新FormStore
- 全局会导致全局污染,先后顺序不确定(保证new发生在myRcfieldform之前)
- 闭包在函数组件内部成本很高 解决 useRef 存在对应组件的fiber上,在卸载前指向同一个值
通过Form组件传递给Filed组件,context 1.创建context对象 2.使用context.provider传递value 3.子组件消费value 3.1 contextType:只能在类组件,只能订阅单一的context来源 3.2 useContext:只能函数组件 3.3 Context.Consumer
store改变后,更新组件 field订阅一下(将field的实例存进去),让store里面负责更新的数组多了一个值,触发更新
注意:订阅和取消订阅,注册与取消注册成对出现
submit
1.form禁止默认事件 2.field实例存在了formStore里面可以通过form调用其中的sunmit方法来获取value值
适配类组件
formjs里面 const [formInstance] = useForm(form) useForm里面判断一下
ref适配问题 const Form = React.forwardRef(_Form) 类组件里面 formRef = React.createRef();
form组件里面,接收ref,将新的useRef()传给父组件 React.useImperativeHandle(ref,() => formInstance)