简体   繁体   English

通过状态传递onChange事件

[英]Passing onChange events through the state

I am creating a form component and I want to be able to pass on change elements per form element and I cannot seem to get it work properly. 我正在创建一个表单组件,并且希望能够传递每个表单元素的更改元素,但似乎无法正常工作。

I have my LoginComponent 我有我的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;

As you can see I want to pass in the handle function in the state of the component so I can uniquely handle form inputs. 如您所见,我想在组件状态下传递handle函数,以便我可以唯一地处理表单输入。 When I run this code though it fails because I cannot pass a function in the state. 当我运行此代码时,它失败了,因为无法在状态中传递函数。 Is this type of request allowed or able to accomplish in another way? 这种请求类型是否被允许或能够以其他方式完成?

I know you can pass the bound function to the component directly but the form component is dynamically built based on the state.item array. 我知道您可以将绑定函数直接传递给组件,但是表单组件是基于state.item数组动态构建的。

Here is my form component 这是我的表单组件

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;

As you can see in the formItems I am trying to create the elements with the onChange function from the state passed in. Any help or suggestions would be appreciated. 正如您在formItems中看到的那样,我正在尝试从传入的状态使用onChange函数创建元素。我们将不胜感激。 I am well aware also I can just make the form component a component that loads all children passed so you basically build the form in the login component without state but I would prefer that not be the case. 我也很清楚,我可以使表单组件成为可以加载所有传递的所有子组件的组件,因此您基本上是在登录组件中不带状态的情况下构建表单,但我希望情况并非如此。

Storing methods in state to be passed to children is usually a bad idea. 在状态中存储要传递给孩子的方法通常是个坏主意。 I propose an alternative. 我提出一个替代方案。

Consider the onChange function, that will still reside in LoginComponent and will be passed as a prop to the <FormComponent /> 考虑onChange函数,该函数仍将驻留在LoginComponent ,并将作为道具传递给<FormComponent />

The handler is written as such that you'll be able to identify which child component called it, by taking it's name attribute too, eliminating the need to make a unique handler for each input. 处理程序的编写方式使您也可以通过使用其name属性来标识调用它的子组件,从而无需为每个输入创建唯一的处理程序。

LoginComponent: 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>
    );
  }

Then when you are iterating over and constructing your InputComponent , pass this to it's onChange : 然后,当您遍历并构造InputComponent ,请将InputComponent传递给它的onChange

FormComponent: 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: Don't forget to bind your functions or use arrow functions. PS:不要忘记bind功能或使用箭头功能。

Try implementing same function handleChange to handle all form value change. 尝试实现相同的功能handleChange以处理所有表单值更改。

React onChange function pass event argument. 反应onChange函数传递事件参数。 With event argument perform necessary logic. 使用事件参数执行必要的逻辑。 Do not need onChange key in form object in state. 处于状态的表单对象中不需要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 } /> 

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

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