无法读取未定义的属性'bind'

时间:2017-10-08 13:35:55

标签: javascript reactjs

请不要先将它标记为重复请阅读我的问题,我尝试在构造函数中绑定我的函数并尝试绑定但仍然是我收到错误“无法读取未定义的属性'绑定'。 “当我从构造函数中删除bind时,它给了我updateComment的错误。我的意思是说我试图绑定它但没有任何帮助。

代码:

<!Doctype html>
<html>
    <head>
        <title>React Practice</title>
        <link rel="stylesheet" href="main.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
    </head>
    <body>
        <script type="text/jsx">
            class Basics extends React.Component
            {
                constructor () {
                    super();
                    this.state = {editing:false};
                }
                edit () {
                    this.setState({editing:true});
                }
                save () {
                    this.setState({editing:false});
                    this.props.upComment(this.refs.newText.value, this.props.index);
                }
                remove () {
                    this.props.delComment(this.props.index);
                }
                renderNormal () {
                    return (
                        <div>
                            <div className="commentText">{this.props.children}</div>
                            <button onClick={this.edit.bind(this)} className="button-primary">Edit</button>
                            <button onClick={this.remove.bind(this)} className="button-danger">Remove</button>
                        </div>
                    )
                }
                renderForm () {
                    return (
                        <div>
                            <textarea ref='newText' defaultValue={this.props.children}></textarea>
                            <button onClick={this.save.bind(this)} className="button-success">Save</button>
                        </div>
                        )
                }
                render () {
                    if (this.state.editing) {
                        return this.renderForm();
                    } else {
                        return this.renderNormal();
                    }
                }
            }

            class Manage extends React.Component {
                constructor (props) {
                    super(props);
                    this.removeComment = this.removeComment.bind(this);
                    this.upComment = this.upComment.bind(this);
                    this.state = {
                        comments: [
                            'This is a first comment',
                            'Hi there!',
                            'I am learning React'
                        ]
                    }
                }

                removeComment(i) {
                    console.log(i);
                    var arr = this.state.comments;
                    arr.splice(i, 1);
                    this.setState({comments: arr})
                }

                updateComment(newText, i) {
                    console.log('Updating Comment');
                    var arr = this.state.comments; 
                    arr[i] = newText;
                    this.setState({comments: arr})
                }

                render () {
                    return (
                        <div className="board">
                            {this.state.comments.map(function (text,i) {
                                return (<Basics key={i} index={i} upComment={this.updateComment} delComment={this.removeComment}>
                                            {text}
                                        </Basics>)    
                            }  
                            )}
                        </div>
                    )
                }
            };

            ReactDOM.render(<Manage />, document.getElementById('example'));
        </script>  
        <div id="example"></div>
    </body>
</html>

4 个答案:

答案 0 :(得分:2)

您的代码中有多个需要解决的错误。

  1. 绑定错误是因为代码中不存在upComment。你应该绑定的是函数本身(updateComment)而不是道具名称。
  2. 如果在任何函数中使用this变量,则需要绑定它。 renderNormalrenderForm

  3. 就属于这种情况
  4. 当您在Manage的渲染功能中使用this时,您使用的是匿名回调。但是this将绑定到此回调而不是类函数。将其更改为箭头功能有效。

  5. &#13;
    &#13;
    class Basics extends React.Component {
      constructor() {
        super();
        this.state = { editing: false };
        this.renderNormal = this.renderNormal.bind(this);
        this.renderForm = this.renderForm.bind(this);
      }
      edit() {
        this.setState({ editing: true });
      }
      save() {
        this.setState({ editing: false });
        this.props.upComment(this.refs.newText.value, this.props.index);
      }
      remove() {
        this.props.delComment(this.props.index);
      }
      renderNormal() {
        return (
          <div>
            <div className="commentText">{this.props.children}</div>
            <button onClick={this.edit.bind(this)} className="button-primary">Edit</button>
            <button onClick={this.remove.bind(this)} className="button-danger">Remove</button>
          </div>
        )
      }
      renderForm() {
        return (
          <div>
            <textarea ref='newText' defaultValue={this.props.children}></textarea>
            <button onClick={this.save.bind(this)} className="button-success">Save</button>
          </div>
        )
      }
      render() {
        if (this.state.editing) {
          return this.renderForm();
        } else {
          return this.renderNormal();
        }
      }
    }
    
    class Manage extends React.Component {
      constructor(props) {
        super(props);
        this.removeComment = this.removeComment.bind(this);
        this.updateComment = this.updateComment.bind(this);
        this.state = {
          comments: [
            'This is a first comment',
            'Hi there!',
            'I am learning React'
          ]
        }
      }
    
      removeComment(i) {
        console.log(i);
        var arr = this.state.comments;
        arr.splice(i, 1);
        this.setState({ comments: arr })
      }
    
      updateComment(newText, i) {
        var arr = this.state.comments;
        arr[i] = newText;
        this.setState({ comments: arr })
      }
    
      render() {
        return (
          <div className="board">
            {this.state.comments.map((text, i)=> {
              return (
              <Basics key={i} index={i} upComment={this.updateComment} delComment={this.removeComment}>
                {text}
              </Basics>)
            }
            )}
          </div>
        )
      }
    };
    
    ReactDOM.render(<Manage />, document.getElementById("example"));
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    
    <div id="example"></div>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:1)

在定义函数时,您的函数名称为updateComment,但是当您将类的上下文绑定到函数时,您使用的名称为upComment(class { {1}},其中的第3行Manage)这就是您收到错误的原因。

答案 2 :(得分:0)

我认为没有必要在构造函数中绑定方法/函数而是执行此操作

return (
   <Basics key={i} 
   index={i} 
   upComment={()=>this.updateComment()} 
   delComment={()=>this.removeComment()}>
       {text}
   </Basics>)

虽然分配道具将你的功能包装成匿名功能,但它可能有助于我不尝试这个。

答案 3 :(得分:0)

一个问题是.bind()调用全局属性事件会导致function () { [native code] }而不是函数调用,this是全局对象,例如window

一种方法是将editremove定义为static方法,并使用class作为参考

class Test {
  constructor() {}
  static edit() { console.log("edit") }
  renderNormal() {
    const button = `<div onclick="Test.edit()">click</div>`;
    document.body.insertAdjacentHTML("beforeend", button);
  }
}

new Test().renderNormal()

相关问题