如何从子道具React 15.5.0调用父函数

时间:2017-04-09 01:40:23

标签: javascript reactjs es6-class

你好我试图将函数传递给子类并从子类调用它,但是它显示函数的问题是未定义的

  

无法读取未定义

的属性'removeComment'

这是我的代码

父类:

import React from 'react';
import Navbar from './notes';

export default class Board extends React.Component {
    constructor(props, context) {
      super(props, context);
        this.state = {
            comments: [
              'Kingyyy',
              'React',
              'Learning'
            ]
        };
    }
    removeComment() {
      console.log(i);
      var arr = this.state.comments;
      arr.splice(i,1);
      this.setState({comments: arr});
    }
    editComment(newtext, i) {
      console.log(i);
      var arr = this.state.comments;
      arr[i] = newtext;
      this.setState({comments: arr});
    }
    addComment() {
      var text = prompt('enter the new ');
      var arr = this.state.comments;
      arr[arr.length] = text;
      this.setState({comments: arr});
    }
    eachComment(elem, i) {
        return (
            <Navbar key={i} index={i} editComment={(newtext, i) => this.editComment.bind(this)} removeComment={(i) => this.removeComment.bind(this)}>
              {elem}
            </Navbar>
        );
    }
    render() {
        return (
            <div>
            <button onClick={this.addComment} className="btn btn-success">add new comment</button>
            <br />
                {
                  this.state.comments.map(this.eachComment)
                }
            </div>
        );
    }
}

儿童班:

import React from 'react';

export default class Navbar extends React.Component {
    edit() {
        this.setState({
            edit: !this.state.edit
        })
    }
    save() {
        var value = this.refs.newtext.value;
        this.props.editComment(value,this.props.index);
        this.setState({
            edit: !this.state.edit
        })
    }
    remove() {
      this.props.removeComment(this.props.index);
    }
    constructor(props, context) {
      super(props, context);
      this.state = {edit: false};
    }
    normal() {
        return (
            <div>
                <h1>{this.props.children}</h1>
                <button className="btn btn-info" onClick={this.edit.bind(this)}>
                    edit
                </button>
                <button className="btn btn-danger" onClick={this.remove.bind(this)}>
                    remove
                </button>
            </div>
        );
    }
    editing() {
        return (
            <div>
                <textarea ref="newtext" defaultValue={this.props.children}></textarea>
                <br/>
                <button className="btn btn-success" onClick={this.save.bind(this)}>
                    save
                </button>

            </div>
        );
    }
    render() {
        if (this.state.edit) {
            return this.editing();
        } else {
            return this.normal();
        }
    }
}

1 个答案:

答案 0 :(得分:2)

问题是你正在失去你的反应背景。将子类的构造函数更改为此

constructor(props, context) {
    super(props, context);
    this.state = {edit: false};
    this.normal = this.normal.bind(this)
    this.editing = this.editing .bind(this)
}

你在删除电话上调用.bind(this)...但是你绑定的this没有具有状态和道具的反应上下文

我建议的一些优化......

将你的函数定义为内联lambda,这样你就不必每次都在每个函数上调用.bind(this)... aka

edit = () => {
    this.setState({
        edit: !this.state.edit
    })
}
save = () => {
    var value = this.refs.newtext.value;
    this.props.editComment(value,this.props.index);
    this.setState({
        edit: !this.state.edit
    })
}
remove = () => {
  this.props.removeComment(this.props.index);
}
normal = () => {
    return (
        <div>
            <h1>{this.props.children}</h1>
            <button className="btn btn-info" onClick={this.edit}>
                edit
            </button>
            <button className="btn btn-danger" onClick={this.remove}>
                remove
            </button>
        </div>
    );
}
editing = () => {
    return (
        <div>
            <textarea ref="newtext" defaultValue={this.props.children}></textarea>
            <br/>
            <button className="btn btn-success" onClick={this.save}>
                save
            </button>

        </div>
    );
}
父类中的

更改传递函数的方式。尽量避免将内联lambda作为元素或反应类(在渲染中)的属性。随着网站变得越来越复杂,它将导致性能问题。

eachComment = (elem, i) => {
    return (
        <Navbar key={i} index={i} editComment={this.editComment} removeComment={this.removeComment}>
          {elem}
        </Navbar>
    );
}

如果你需要将自定义变量传递给内联定义的函数,你可以使用.bind来传递它们而不是lambda(bind比lambda更高效... aka

someList.map( (item, i) => <SomeElement onUserClick={this.handleUserClick.bind(null, item) />);

.bind()的第一个参数是上下文this,您可以传递null以不覆盖上下文。然后你可以将任何其他参数传递给函数,作为在被调用的调用上扩展的参数。