如何从 child prop React 15.5.0 调用 parent 函数

How to call parent function from child prop React 15.5.0

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

Cannot read property 'removeComment' of undefined

这是我的代码

parent class:

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

child class:

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();
        }
    }
}

问题是你失去了你的反应上下文。将 child class 的构造函数更改为此

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

你在你的 remove 调用中调用了 .bind(this)...但是你正在绑定的 this 没有带有 state 和 props 的反应上下文

我建议的一些优化..

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

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

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

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

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

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

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