2017-10-16 47 views
0

在我编写的书的一部分中,它解释了孩子组件如何访问父母方法。这是如何将一个Parent组件的方法传递给React中的一个孩子的方法?

从孩子到父母的沟通方式是将回调从父母传递给孩子,孩子可以调用它来实现特定的任务。在这种情况下,您将createIssue作为从IssueTable到IssueAdd的回调属性传递。从孩子,你只需调用处理函数中的传入函数来创建一个新问题。

作者提到IssueTable(兄弟姐妹)至IssueAdd(兄弟姐妹),他可能是指IssueList(父级)IssueAdd(孩子) - 右?

,我觉得只是通过检查返回JSXIssueList ...

我们可以看到IssueTable是同级IssueAdd,不是吗?

const contentNode = document.getElementById('contents'); 

class IssueFilter extends React.Component { 
    constructor(props) { 
    super(props); 
    } 
    render() { 
    return (
     <div> 
     This is placeholder for the Issue Filter.{this.props.name} 
     {this.props.age} 
     </div> 
    ); 
    } 
} 

const IssueRow = props => (
    <tr> 
    <td>{props.issue.id}</td> 
    <td>{props.issue.status}</td> 
    <td>{props.issue.owner}</td> 
    <td>{props.issue.created.toDateString()}</td> 
    <td>{props.issue.effort}</td> 
    <td>{props.issue.completionDate ? props.issue.completionDate.toDateString() : ''}</td> 
    <td>{props.issue.title}</td> 
    </tr> 
); 

function IssueTable(props) { 
    const issueRows = props.issues.map(issue => <IssueRow key={issue.id} issue={issue} />); 
    return (
    <table className="bordered-table"> 
     <thead> 
     <tr> 
      <th>Id</th> 
      <th>Status</th> 
      <th>Owner</th> 
      <th>Created</th> 
      <th>Effort</th> 
      <th>Completion Date</th> 
      <th>Title</th> 
     </tr> 
     </thead> 
     <tbody>{issueRows}</tbody> 
    </table> 
); 
} 

class IssueAdd extends React.Component { 
    constructor(props) { 
    super(props); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    handleSubmit(e) { 
    e.preventDefault(); 
    var form = document.forms.issueAdd; 
    console.log('form', document.forms); 
    this.props.createIssue({ 
     owner: form.owner.value, 
     title: form.title.value, 
     status: 'New', 
     created: new Date() 
    }); 
    //clear the form for the next input 
    form.owner.value = ''; 
    form.title.value = ''; 
    } 

    render() { 
    return (
     <div> 
     <form name="issueAdd" onSubmit={this.handleSubmit}> 
      <input type="text" name="owner" placeholder="Owner" /> 
      <input type="text" name="title" placeholder="Title" /> 
      <button>Add</button> 
     </form> 
     </div> 
    ); 
    } 
} 

class IssueList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { issues: [] }; 
    this.createIssue = this.createIssue.bind(this); 
    } 

    componentDidMount() { 
    this.loadData(); 
    } 

    loadData() { 
    fetch('/api/issues') 
     .then(response => response.json()) 
     .then(data => { 
     console.log('Total count of records:', data._metadata.total_count); 
     data.records.forEach(issue => { 
      issue.created = new Date(issue.created); 
      if (issue.completionDate) issue.completionDate = new Date(issue.completionDate); 
     }); 
     this.setState({ issues: data.records }); 
     }) 
     .catch(err => { 
     console.log(err); 
     }); 
    } 

    createIssue(newIssue) { 
    fetch('/api/issues', { 
     method: 'POST', 
     headers: { 'Content-Type': 'application/json' }, 
     body: JSON.stringify(newIssue) 
    }) 
     .then(response => { 
     if (response.ok) { 
      response.json().then(updatedIssue => { 
      updatedIssue.created = new Date(updatedIssue.created); 
      if (updatedIssue.completionDate) updatedIssue.completionDate = new Date(updatedIssue.completionDate); 
      const newIssues = this.state.issues.concat(updatedIssue); 
      this.setState({ issues: newIssues }); 
      }); //**/ 
     } else { 
      response.json().then(error => { 
      alert('Failed to add issue: ' + error.message); 
      }); 
     } 
     }) 
     .catch(err => { 
     alert('Error in sending data to server: ' + err.message); 
     }); 
    } 

    render() { 
    return (
     <div> 
     <h1>Issue Tracker</h1> 
     <IssueFilter /> 
     <hr /> 
     <IssueTable issues={this.state.issues} /> 
     <hr /> 
     <IssueAdd createIssue={this.createIssue} /> 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<IssueList />, contentNode); 

所以总之,所有人必须做的,以利用在父项中声明的函数是以下....?

const contentNode = document.getElementById('contents'); 


class ChildComponent extends React.Component { 
    constructor(props) { 
    super(props); 
     this.props.someFunc; //So naming this prop someFunc will just help us identify this prop should get the function from the parent? 
    } 
} 

class Parent extends React.component{ 
    constructor(props) { 
    super(props); 
     this.someFunc = this.someFunc.bind(this); 
    } 

    someFunc(){ 
    .... 
    } 

    render() { 
    return (
     <div> 
     <ChildComponent someFunc={this.someFunc} /> // Parent's someFunc gets passed as a value to the ChildComponent's prop which is someFunc? 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<Parent />, contentNode); 
+1

组件布局的方式,您发布的描述是错误的,而且您是对的:createIssue回调从IssueList传递到IssueAdd。 – nbkhope

+1

IssueList的子代是:IssueFilter,IssueTable和IssueAdd。 – nbkhope

回答

1

IssueTableIssueAdd是从代码的事实兄弟姐妹片断您发布。

class ChildComponent extends React.Component { 
    constructor(props) { 
    super(props); 
     this.props.someFunc; //So naming this prop someFunc will just help us identify this prop should get the function from the parent? 
    } 
} 

在上面的代码中this.props.someFunc不会起任何作用,它只会返回你从ParentComponent发送,但什么都不会发生作用。

如果您打算修改或更改ChildComponent中某个操作的父项状态,则以下代码段可能会更有意义。

class ChildComponent extends React.Component { 
    constructor(props) { 
    super(props);   
    } 

    handleOnClick = (event) => { 
    // The name is someFunc because that is what you sent as props from the 
    // ParentComponent <ChildComponent someFunc={this.someFunc} /> 

    // If it had been <ChildComponent callbackToParent={this.someFunc} /> 
    // then you should access the function as this.props.callbackToParent 
    // and invoke as this.props.callbackToParent() 

    this.props.someFunc(); 
    } 

    render() { 
    return (
     <div onClick={this.handleOnClick}> 
     Click to trigger callback sent by parent 
     </div> 
    ) 
    } 
} 
相关问题