2017-10-16 51 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> 
    ) 
    } 
} 
相關問題