【问题标题】:best way to abstract forms and inputs using React functional components?使用 React 功能组件抽象表单和输入的最佳方法?
【发布时间】:2021-12-26 20:20:42
【问题描述】:

我是 React 的新手,尤其是钩子和功能组件, 我建立了一个网站,和任何其他网站一样,我需要避免重复自己,并抽象我的代码以供重用, 我使用类创建了抽象表单并继承了表单并像这样添加:

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

我想使用功能组件做同样的事情,我尝试使用 HOC,但是如果我必须通过 props 在输入中传递我需要的所有信息,那会很混乱, 使用带有 props 的其他组件组合组件也不像使用基于类的组件继承那么容易! 我可以实现一些组合并使代码更可重用,但我不知道是否有任何具体的东西可以使代码更易于与功能组件一起使用!

【问题讨论】:

  • 如果您的表格变得复杂,您可能需要考虑类似formik.org
  • 请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。

标签: javascript reactjs react-hooks code-reuse


【解决方案1】:

因此,您想创建一个表单并提取其中的任何内容,然后使用states 将其存储在一个对象中。

  1. 您将从react 导入useState() 并创建一个空对象
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. 在前面定义的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>
    )
}

在上面的代码中,e.target.value 使用event object 从作为输入标签的 html 标签中提取值。 onChange 属性会在您每次更改内容或输入输入标签时触发。 也可以参考这个代码here

【讨论】:

  • 我想知道功能组件的代码重用的最佳方法。我不认为你的代码存档了!
猜你喜欢
  • 2021-12-18
  • 2020-03-10
  • 2021-09-29
  • 2021-05-01
  • 2011-02-19
  • 2019-08-29
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
相关资源
最近更新 更多