首页 > 解决方案 > 动态生成时反应表单元素 onchange 事件不起作用

问题描述

我正在尝试从数据中生成输入列表,并让它们作为受控输入来捕获它们的数据。文本输入似乎得到了很好的捕获,但是文件输入 onchange 事件得到了错误"TypeError: _this2.handleFileInputChange is not a function"。如果我将它从箭头函数中取出,我不会收到错误消息,但回调仍然不起作用。各位法师怎么看?

- - - - - 编辑 - - - - - - -

实现了将函数定义为箭头函数的建议,这很好,但文件输入似乎仍然没有像其他字段那样触发更改事件。我开始认为这是组件的限制。

还有其他想法吗?谢谢!

import React from "react";
// import { Link } from "gatsby";
import Layout from "../components/layout";
import {Form,InputGroup,Button} from 'bootstrap-4-react'


function camelize(str) {
  return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
    return index === 0 ? word.toLowerCase() : word.toUpperCase();
  }).replace(/\s+/g, '');
}

const formContent = [
    ["Profile Name","Ex. College soccer profile Spring 2020","text"],
    ["Player Name", "Ex. Jose Greer", "text"],
    ["Player Profile Photo", "Ex. Jose Greer", "file"]
]



class ProfileForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      profileName: '',
      playerName: '',
      profileImageFilename: '',
    };
  }

  

  handleFileInputchange = (e) => {
    console.log(e.target.files[0]);
    this.setState({profileImageFilename: e.target.files[0].filename})
  }

  handleInputChange = (e) => {
    console.log(e)
    this.setState({[e.target]: e.target.value})
  }

  handleSubmit = (e) => {
    console.log(e)
    e.preventDefault()
  }

  createFormGroup(i) {
    const title = i[0],
      placeholder = i[1],
      type = i[2]
    const titleCamelCase = camelize(title);
    if (type === "file") {
      return (
        <>
          <label key={titleCamelCase + "-label"} htmlFor={titleCamelCase}>
            Player Profile Image
          </label>
          <InputGroup key={titleCamelCase + "-group"} mb="3">
            <Form.CustomFile
              required
              onChange={this.handleFileInputChange}
              key={titleCamelCase + "-file"}
              id={titleCamelCase}
              accept=".jpg, .jpeg, .png"
            >
              {this.state.profileImageFilename
                ? this.state.profileImageFilename
                : "Choose an image. ( .jpg, .jpeg, .png, .gif )"}
            </Form.CustomFile>
          </InputGroup>
        </>
      );
    }

    return (
      <>
        <label key={titleCamelCase + "-label"} htmlFor={titleCamelCase}>
          {title}
        </label>
        <Form.Input
          key={titleCamelCase + "-input"}
          mb="3"
          required
          type={type}
          id={titleCamelCase}
          placeholder={placeholder}
          onChange={this.handleInputChange}
          valule={this.state[titleCamelCase]}
        />
      </>
    );
  }

  render() {
    return (
      <Layout>
        <Form onSubmit={this.handleSubmit}>
          <Form.Group>
            {/* {formContent.map(function(i){this.createFormGroup(i)}.bind(this))} */}
            {formContent.map((i)=>this.createFormGroup(i))}
          </Form.Group>
          <Button primary type="submit">
            Submit
          </Button>
        </Form>
      </Layout>
    );
  }
}

export default ProfileForm

标签: javascriptreactjsgatsby

解决方案


问题

this类组件的 未绑定到回调handleFileInputchange处理程序。

解决方案

您应该绑定this到或将handleFileInputchangeconstructor声明为箭头函数。

constructor(props) {
  super(props);
  this.state = {
    profileName: '',
    playerName: '',
    profileImageFilename: '',
  };

  this.handleFileInputchange = this.handleFileInputchange.bind(this);
}

或者

handleFileInputchange = (e) => {
  console.log(e);
  this.setState({ profileImageFilename: e.target.file[0].filename });
}

您还可以安全地删除匿名回调并直接传递this.handleFileInputChange,因为onChange事件处理程序和您的回调具有相同的函数签名:

onChange={this.handleFileInputChange}

更新

我用你的代码创建了一个代码。奇怪的是,我也没有看到任何 onChange 回调触发(控制台日志),我什componentDidUpdate至添加了一个日志状态更新,这也不会触发。我可以添加一个新文件并查看带有我选择的文件名的文本工具提示,但 UI 中没有任何更新。如果您的引导输入仍然导致问题,我建议实施原始输入元素。


推荐阅读