我正在创建一个表单组件,并且希望能够传递每个表单元素的更改元素,而我似乎无法使其正常工作。
我有我的LoginComponent
import React from "react";
import './LoginComponent.css';
import FormComponent from '../FormComponent/FormComponent';
class LoginComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
header: "Login",
id: "login-form",
name: "login-form",
items: [
{
element: "input",
type: "email",
id: "lf-email",
name: "lf-email",
value: "",
onChange: this.handleOnChangeEmail.bind(this),
placeholder: "Email",
img: {},
},
{
element: "input",
type: "password",
id: "lf-password",
name: "lf-password",
value: "",
onChange: ,
placeholder: "Password",
img: {},
},
{
element: "checkbox",
id: "lf-remember-me",
name: "lf-remember-me",
value: "lf-remember-me",
onChange: ,
display: "Remember Me",
isSelected: false
}
]
}
}
// Figure out how to pass onChange functions per item in state.
handleOnChangeEmail(e) {
console.log("Email changed");
}
render() {
return (
<div className="LoginComponent">
{/*
Create onSubmit function for submitting the form
Create handle change functions for inputs
*/}
<FormComponent id={ this.state.id } name={ this.state.name } onSubmit="" header={ this.state.header } items={ this.state.items } />
</div>
);
}
}
export default LoginComponent;
如您所见,我想在组件状态下传递handle函数,以便我可以唯一地处理表单输入。当我运行此代码时,它失败了,因为无法在状态中传递函数。这种请求是否被允许或能够以其他方式完成?
我知道您可以将绑定函数直接传递给组件,但是表单组件是根据state.item数组动态构建的。
这是我的表单组件
import React from "react";
import './FormComponent.css';
import InputComponent from './InputComponent/InputComponent';
import FormHeaderComponent from './FormHeaderComponent/FormHeaderComponent';
import CheckboxComponent from "./CheckboxComponent/CheckboxComponent";
class FormComponent extends React.Component {
render() {
const formItems = this.props.items.map((item) => {
switch(item.element) {
case "input":
return <InputComponent type={ item.type } id={ item.id } name={ item.name } placeholder={ item.placeholder } value={ item.value } onChange={ item.onChange } />
case "checkbox":
return <CheckboxComponent id={ item.id } name={ item.name } value={ item.value } selected={ item.isSelected } onChange={ item.onChange } display={ item.display } />
default:
return <InputComponent />;
}
});
return (
<form id={ this.props.id } name={ this.props.name }>
<FormHeaderComponent header={ this.props.header } />
{/*
Setup handling of submit functions
Setup handling of onchange function for inputs
*/}
{ formItems }
</form>
);
}
}
export default FormComponent;
正如您在formItems中看到的那样,我正在尝试从传入的状态使用onChange函数创建元素。任何帮助或建议都将不胜感激。我也很清楚,我可以使表单组件成为加载所有通过的子组件的组件,因此您基本上在登录组件中构建表单而没有状态,但是我不希望这样。
答案 0 :(得分:1)
在状态中存储要传递给孩子的方法通常不是一个好主意。我提议一种替代方法。
考虑onChange
函数,该函数仍将驻留在LoginComponent
中,并将作为道具传递给<FormComponent />
编写处理程序时,您也可以通过使用其name
属性来标识调用它的子组件,而无需为每个输入都创建唯一的处理程序。
LoginComponent:
handleOnChangeEmail(e) {
const { name, value } = e.target;
console.log(`${name} changed to ${value}`);
}
render() {
return (
<div className="LoginComponent">
<FormComponent
id={this.state.id}
name={this.state.name}
onSubmit=""
header={this.state.header}
items={this.state.items}
formOnChange={this.handleOnChangeEmail}
/>
</div>
);
}
然后,当您遍历并构造InputComponent
时,请将其传递给onChange
:
FormComponent:
class FormComponent extends React.Component {
render() {
const formItems = this.props.items.map(item => {
switch (item.element) {
case "input":
return (
<InputComponent
type={item.type}
id={item.id}
name={item.name}
placeholder={item.placeholder}
value={item.value}
onChange={this.props.formOnChange}
/>
);
case "checkbox":
return (
<CheckboxComponent
id={item.id}
name={item.name}
value={item.value}
selected={item.isSelected}
onChange={this.props.formOnChange}
display={item.display}
/>
);
default:
return <InputComponent />;
}
});
return (
<form id={this.props.id} name={this.props.name}>
<FormHeaderComponent header={this.props.header} />
{formItems}
</form>
);
}
}
PS:请不要忘记bind
您的功能或使用箭头功能。
答案 1 :(得分:1)
尝试实现相同的功能handleChange以处理所有表单值更改。
反应onChange函数传递事件参数。使用事件参数执行必要的逻辑。处于状态的表单对象中不需要onChange键。
// use lodash library for array handling.
// yarn add lodash
// import {indexOf} from "lodash"
// using fat arrow will save from binding function in constructor.
handleChange=({target})=> {
const {items} = this.state;
// target.name/id will give the element state can be update as required.
let index = indexOf(items, {name:target.name})
items[index].value = target.value;
this.setState({
items
})
}
// remove handle change from items and just user it for all form value change.
<FormComponent id={ this.state.id } name={ this.state.name } handleChange={this.handleChange} onSubmit="" header={ this.state.header } items={ this.state.items } />