简体   繁体   English

使用 React 功能组件抽象 forms 和输入的最佳方法?

[英]best way to abstract forms and inputs using React functional components?

I am kind of new to React and especially to the hooks and functional components, I building a website, and like any other website, I need to avoid repeating myself, and abstract my code for reuse, I created abstracted forms using classes and inherited the form and added on it like this:我是 React 的新手,尤其是钩子和功能组件,我建立了一个网站,和任何其他网站一样,我需要避免重复自己,并抽象我的代码以供重用,我使用类创建了抽象的 forms 并继承了表格并添加如下:

class InputForm extends React.Component {
  state: {}
  validate = () => {
    const { error } = Joi.validate(this.state.data, this.schema)
    if (!error) {
      return null
    } else {
      const errors = {}
      error.details.map((oneError) => {
        errors[oneError.path[0]] = oneError.message
        return errors
      })
      return errors
    }
  }
  validateProperty = ({ name, value }) => {
    const obj = { [name]: value }
    const schema = Joi.object({ [name]: this.schema[name] })
    const errors = {}
    const { error } = Joi.validate(obj, schema)
    if (!error) {
      return null
    } else {
      error.details.map((oneError) => {
        errors[oneError.path[0]] = oneError.message
        return errors
      })
      return errors ? errors : null
    }
  }
  handleSubmit = (e) => {
    console.log('calling handleSubmit line 1')
    let { errors } = { ...this.state }

    e.preventDefault()
    if (!errors) {
      console.log('no errors')
      return
    } else {
      errors = this.validate() || {}
      console.log('errors values are: ', errors)
      if (Object.keys(errors).length === 0) {
        console.log('calling do submit in handleSubmit')
        this.doSubmit(e)
      }

      this.setState({ errors })
    }
    console.log('done submitting')
  }
  handleOnChange = ({ currentTarget: input }) => {
    let { data, errors } = { ...this.state }
    data[input.name] = input.value
    errors = this.validateProperty(input) || {}

    this.setState({ data, errors })
  }
/// you can see I use this to renender any input
  renderInputField = (
    name,
    label,
    type,
    message,
    onChangeParams = this.handleOnChange,
    ...rest
  ) => {
    const { data, errors } = { ...this.state }
    return (
      <InputField
        {...rest}
        name={name}
        value={data[name]}
        label={label}
        onChange={(e) => {
          this.handleOnChange(e)
          onChangeParams(e)
        }}
        type={type}
        message={message}
        errors={errors[name]}
      ></InputField>
    )
  } 
/// you can see I use this to renender any drop down input
  renderInputFieldDD = (name, label, type, message, options, ...rest) => {
    const { data, errors } = { ...this.state }
    return (
      <InputFieldDD
        {...rest}
        name={name}
        value={data[name]}
        label={label}
        onChange={this.handleOnChange}
        type={type}
        message={message}
        options={options}
        errors={errors[name]}
      ></InputFieldDD>
    )
  }
  renderButton = (label) => {
    return (
      <button
        onClick={this.handleSubmit}
        type='submit'
        className='btn btn-primary'
      >
        {label}
      </button>
    )
  }
}

export default InputForm

I wanted to do the same thing using functional components, I tried using HOC, but that is quite messed if I had to pass all the info I need in an input via props, composing components using other ones with props is not as easy as inheritance using class-based components either, I could achieve some composition and make code more reusable, but I don't know if there is anything specific that will make code more reusable with functional components!我想使用功能组件做同样的事情,我尝试使用 HOC,但是如果我必须通过道具在输入中传递我需要的所有信息,那会很混乱,使用其他带有道具的组件组合组件不像 inheritance 那样容易使用基于类的组件,我可以实现一些组合并使代码更可重用,但我不知道是否有任何特定的东西可以使代码更可重用功能组件!

So you want to create a form and extract whatever filled in it and store it inside an object using states .因此,您想创建一个表单并提取其中填写的任何内容,然后使用states将其存储在 object 中。

  1. You'll import useState() from react and create an empty object您将从react导入useState()并创建一个空的 object
import {useState} from 'react';

const FormComponent = () =>{
    const [data,setData] = useState({name:"",age:""}) 
    // this hook returns 2 values, the state and a function to update it that takes a single argument that is the updated state value

}
  1. Create a form with onChange attribute in every input tag inside FormComponent defined earlier.在前面定义的FormComponent内的每个输入标记中创建一个具有onChange属性的表单。
const FormComponent = () =>{
    return (
        <form>
            <input type="text" value={data.name} placeholder="Name" onChange={(e)=>setData({...data,data.name:e.target.value})}/>

            <input type="text" value={data.age} placeholder="Age" onChange={(e)=>setData({...data,data.age:e.target.value})}/>
        </form>
    )
}

In the above code the e.target.value extracts the value from the html tag that is the input tag here using the event object .在上面的代码中, e.target.value从 html 标记中提取值,该标记是此处使用event object的输入标记。 The onChange attribute triggers every time you change something or type in the input tag.每次您更改某些内容或在输入标记中键入时,都会触发onChange属性。 You can also refer to this code here您也可以在此处参考此代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM