[英]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 中。
useState()
from react
and create an empty object您将从react
导入useState()
并创建一个空的 objectimport {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
}
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.