【问题标题】:Value of this is undefinedthis 的值未定义
【发布时间】:2020-01-21 21:03:48
【问题描述】:

我在 if 语句中有一个 this 值,嵌套在我的 handleFormChange 函数中。我尝试使用带有此函数的箭头函数来绑定 this 的值,但我收到以下错误消息:

TypeError: Cannot set property 'author' of undefined

据我了解,通常您可以通过查看包含this 的函数的调用位置来找到this 的值。但是,就我而言,我正在努力解决这个问题。谁能向我解释为什么它是未定义的以及如何解决这个问题?代码如下:

class CommentForm extends React.Component{

    constructor(props){
        super(props)


        var comment={author:'', message:''}
    }


    handleSubmit= (e)=>{
        e.preventDefault()
        var authorVal = this.comment.author;
        var textVal = this.comment.message;
        //this stops any comment submittal if anything missing
        if (!textVal || !authorVal) {
         return;
        }
        this.props.onCommentSubmit(this.comment);
        //reset form values
        e.target[0].value = '';
        e.target[1].value = '';
        return;
    }


    handleFormChange= (e)=>{
        e.preventDefault()
        if(e.target.name==='author'){
            var author = e.target.value.trim();
            this.comment.author = author
        }else if(e.target.name==='message'){
            var message = e.target.value.trim();
            this.comment.message = message
        }
    }

    render() {
    return (

        <form className = "ui form" method="post" onChange={(e)=>{this.handleFormChange(e)}} onSubmit={(e)=>{this.handleSubmit(e)}}>
          <div className="form-group">
            <input
              className="form-control"
              placeholder="user..."
              name="author"
              type="text"
            />
          </div>

          <div className="form-group">
            <textarea
              className="form-control"
              placeholder="comment..."
              name="message"        
            />
          </div>



          <div className="form-group">
            <button disabled={null} className="btn btn-primary">
              Comment &#10148;
            </button>
          </div>
        </form>

    );
  }
}

export default CommentForm

【问题讨论】:

  • var 注释
  • 你从来没有在this中发表评论。 this.comment = {author:'', message:''}
  • 不是说this 未定义,而是说this.comment 未定义。
  • 有人能解释一下为什么在声明变量时需要使用this吗?以前我从未在构造函数中使用this 声明变量,除非它是状态
  • this 指的是类实例范围,但是如果您在其中声明一个变量,它将仅在该块范围(构造函数)上可用,因此如果您想从另一个块中检索它,它不会在那里。 this 范围在该类实例的所有块中都可用。您应该阅读有关面向对象编程的更多信息。

标签: javascript reactjs this


【解决方案1】:

学习如何做你想做的事的第一步是研究 React 的 State 是如何工作的(official docs 擅长解释它)。

这个例子并不完整,但应该指导您完成整个过程。

class CommentForm extends Component {

constructor(props) {
  super(props);

  this.state = {
    author  : '',
    message : '',
  }

  this.onChangeAuthorName = this.onChangeAuthorName.bind(this);
  this.onBlurAuthorName   = this.onBlurAuthorName.bind(this);
}

onChangeAuthorName(e) {
  this.setState({ author: e.target.value });
}

onBlurAuthorName() {
  // trim on blur (or when you send to the network, to avoid
  // having the user not being able to add empty whitespaces
  // while typing
  this.setState({ author: this.state.author.trim() })
}

render() {
  return (
    ...
    <input value={this.state.author} onChange={this.onChangeAuthorName} onBlur={this.onBlurAuthorName} />
    ...
  );
}

}

通常,当您想在 React 中“设置”变量时,您不会像在 Javascript 类 (this.comment = e.target.value) 中那样添加它们,而是使用函数 setState()。来自文档:

// Wrong
this.state.comment = 'Hello';

Instead, use setState():

// Correct
this.setState({comment: 'Hello'});

(注意:或者,这可以使用 React Hooks 完成,但我建议您直接学习生命周期方法。祝你好运!)

【讨论】:

  • 我在Code Sandbox 上为 OP 做了一个类似的工作示例。假设 props.onCommentSubmit 函数是异步的,在 Promise 上成功调用 then 后清除表单是有意义的。如果是同步的,请移除我的then 调用并在提交后直接清除它。
  • @ReedDunkle 谢谢!您的示例几乎是正确的,但需要进行重要的编辑! this.state 应该在构造函数内声明alwayssuper(props) 应该是构造函数内的第一行(除非使用钩子)。 Here's why, from Dan Abramov himself.
  • 我假设使用property-initializer。但我不应该这样假设。这可能与用例更相关:React docs。我更新了沙箱以使用constructor
【解决方案2】:

即使你提出了正确的答案,我还是决定写下来,原因很简单,我认为我的代码更接近它发布的内容。

import React, { Component } from "react";
import ReactDOM from "react-dom";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      comment: {},
      some: 1
    };
  }

  handleFormChange = e => {
    e.preventDefault();
    let { comment } = this.state;
    const newCommentState = function() {
      let returnObj = { ...comment };
      returnObj[this.target.name] = this.target.value.trim();
      return returnObj;
    }.bind(e)();
    this.setState({ comment: newCommentState });
  };

  handleSubmit = e => {
    e.preventDefault();
    let { comment } = this.state;
    if (!comment.author || !comment.message) return;

    this.props.onCommentSubmit(comment);
    this.setState({ comment: {} });
    e.target[0].value = "";
    e.target[1].value = "";
  };

  render() {
    return (
      <div>
        <form
          className="ui form"
          method="post"
          onChange={e => {
            this.handleFormChange(e);
          }}
          onSubmit={e => {
            this.handleSubmit(e);
          }}
        >
          <div className="form-group">
            <input
              className="form-control"
              placeholder="user..."
              name="author"
              type="text"
            />
          </div>

          <div className="form-group">
            <textarea
              className="form-control"
              placeholder="comment..."
              name="message"
            />
          </div>

          <div className="form-group">
            <button disabled={null} className="btn btn-primary">
              Comment &#10148;
            </button>
          </div>
        </form>
      </div>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

活生生的例子:

【讨论】:

    猜你喜欢
    • 2016-08-21
    • 2018-10-06
    • 1970-01-01
    • 2018-04-09
    • 2016-01-27
    • 2019-12-29
    • 2021-06-08
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多