传递功能作为道具

时间:2018-04-09 10:59:58

标签: node.js reactjs

我无法理解如何在React中将父组件中的函数调用到子组件。它只调用TestEvent中的函数并在表单上呈现旧数据。控制不去管理评论的组件功能。



class TestEvent extends Component{
constructor(props){
  super(props);
  this.state={
    editing:false,
    comment:this.props.comment   
  };
  this.commentRef=React.createRef(); // to create a ref to the DOM element
}

  edit(){
    this.setState({editing:true}) ;   
  }
  save(){   
    this.setState({editing:false});
    this.props.updatecomment.bind(this.commentRef.current.value,this.props.index);
  }
  remove(){   
    this.props.deletecomment.bind(this.props.index);
  }

renderNormal(){
 return(    
      <div className="commentContainer">
        <div className="commentText">{this.state.comment}</div>
        <div className="commentBtn">
        <button className="b1" onClick={this.edit.bind(this)} >Edit</button>
        <button className="b2" onClick={this.remove.bind(this) } >Remove</button>  
       </div>
      </div>
    );}
renderForm(){
  return(   
    <div className="commentContainer">
    <textarea ref={this.commentRef} defaultValue={this.state.comment}></textarea>         
      <div className="commentBtn">
      <button className="b3" onClick={this.save.bind(this)} >Save</button>        
      </div>
    </div>
  );
}
  render(){ 
   if(this.state.editing){
   return this.renderForm();
   }else{
   return this.renderNormal();
   }
  }
}

// Need to manage comments from separate component here
class ManageComment extends Component{
  constructor(props){
    super(props);
    this.state= {
      comments:[
                'First comment',
                'Second Comment',
                'Third comment'
              ]}              
  }
  // add functions to remove,edit comments from child
  // passing functions as a props
  updateComment(newComment,i){
    var arr=this.state.comments;
    arr[i]=newComment;
    this.setState({comments:arr});
  }
  deleteComment(i){
    var arr=this.state.comments;
    arr.splice(i,1);
    this.setState({comments:arr});    
  }
    render(){
      return(
            <div className="manageComment">
            {
              this.state.comments.map(function(text,i){
                return (
                  <TestEvent
                   key={i}              
                   index={i}
                   comment={text}
                   updatecomment={this.updateComment.bind(text,i)} 
                   deletecomment={this.deleteComment.bind(i)}> </TestEvent>);
              },this)            
            }
            </div>
      );
    
  }
}
&#13;
&#13;
&#13;

。 我创建了一个表单,用于在textarea中输入评论,并提供编辑/保存/删除评论的选项。

我的代码详情:

  1. 我已经创建了&#39; TestEvent&#39;组件,其中我有3个选项,保存,删除和编辑以对评论文本进行操作。
  2. 然后我&#39; ManageComment&#39;组件,我在那里渲染&#39; TestEvent&#39;有一些道具以及我通过名为updatecomment和deletecomment的道具传递函数。
  3. 最后,我正在渲染&#39; ManageComment&#39;组件。
  4. 所以基本上在这里我是父母和孩子的组成部分,我试图调用&#39; ManageComment&#39;来自&#39; TestEvent&#39;。
  5. 的组件

2 个答案:

答案 0 :(得分:0)

问题是你没有调用该函数,只是将()绑定到函数上。例如,在您的函数中,您执行以下操作:

save = () => {   
    this.setState({editing:false});
    this.props.updatecomment.bind(this.commentRef.current.value,this.props.index);
  }

问题是this.props.updatecomment.bind(this.commentRef.current.value,this.props.index);不执行你的函数,只是绑定上下文。我建议你再看看bind。你想要做的是调用你的函数而不是绑定它的东西,例如this.props.updatecomment(this.commentRef.current.value,this.props.index);

为什么你需要一个评论参考?您可以通过保存时调用的事件来访问textarea的值。如果您致电该活动,则可以在event.target中找到相关数据。检查文本区域的值的位置。

  save = (event) {
    this.setState({editing:false});
    const commentValue = event.target
    this.props.updatecomment(commentValue, this.props.index)
  }

我也建议让你的代码更具可读性我建议你使用箭头函数,如果你想绑定组件的上下文

&#13;
&#13;
  class ManageComment extends Component{
    constructor(props){
      super(props);
      this.state= {
        comments:[
                  'First comment',
                  'Second Comment',
                  'Third comment'
                ]}              
    }
    // add functions to remove,edit comments from child
    // passing functions as a props
    updateComment = (newComment,i) =>{
      var arr=this.state.comments;
      arr[i]=newComment;
      this.setState({comments:arr});
    }
    deleteComment = (i) => {
      var arr=this.state.comments;
      arr.splice(i,1);
      this.setState({comments:arr});    
    }
      render(){
        return(
              <div className="manageComment">
              {
                this.state.comments.map(function(text,i){
                  return (
                    <TestEvent
                     key={i}              
                     index={i}
                     comment={text}
                     updatecomment={this.updateComment} 
                     deletecomment={this.deleteComment}> </TestEvent>);
                },this)            
              }
              </div>
        );
      
    }
  }
&#13;
&#13;
&#13;

另一个建议是,您使用letconst代替var。有很多关于为什么不再使用var有意义的文献 - &gt; literature。根据经验,您可以随时使用const,当编译器抱怨切换到let时;

答案 1 :(得分:0)

您已将updateComment()deleteComment()作为名为updatecommentdeletecomment的道具传递给TestEvent组件。但是,这些功能应该这样绑定:

updatecomment={this.updateComment.bind(this)} 
deletecomment={this.deleteComment.bind(this)}

您不需要再次绑定这些功能。这只是使用它的问题:

class TestEvent extends Component {
  ....
  save() {
    this.setState({editing:false})
    this.props.updatecomment(this.commentRef.current.value,this.props.index))
  }

  remove() {
    this.props.deletecomment(this.props.index)
  }
  ....
}