簡體   English   中英

React-從子組件中調用父方法

[英]React - Call parent method from within child component

為菜鳥問題道歉,但我對React很陌生。 我在這里看到了一些與自己堅持的問題類似的問題,但我認為我的要求略有不同。

我正在創建一個Accordion組件,它是子AccordionItem組件的父級。 我為每個AccordionItem賦予了自己的狀態,以跟蹤該項目處於打開還是關閉狀態。 這很好用,現在我有了一個可以使用的手風琴,當您單擊項目的標題時,每個項目都可以打開或關閉。

但是,我現在要添加功能,其中如果AccordionItem已經處於打開狀態,則在選擇另一個AccordionItem時它將關閉。 我相信我將在Accordion.js中需要一個狀態數組或對象,以跟蹤當前選定的AccordionItems,然后在每次單擊時對其進行更新。

我正在努力弄清楚如何將父方法傳遞給子組件。

我的App.js當前如下所示:

class App extends Component {
  render() {
    return (
      <Accordion>
        <AccordionItem title="Question One Title" itemid="question1" openOnLoad onChange={this.updateSelectedItems}>
          <p>here is some text 1</p>
        </AccordionItem>
        <AccordionItem title="Question Two Title" itemid="question2" onChange={this.updateSelectedItems}>
          <p>here is some text 2</p>
        </AccordionItem>
        <AccordionItem title="Question Three Title" itemid="question3" onChange={this.updateSelectedItems}>
          <p>here is some text 3</p>
        </AccordionItem>
      </Accordion>
    );
  }

}

我在網上看到的所有示例都顯示了父級具有一個道具,該道具將對所選父級方法的引用向下傳遞給子級組件。 但是,因為我的AccordionItems是在App.js中定義的,而不是在Accordion.js中定義的,所以此文件中不存在this.updateSelectedItems

我不想將AccordionItems移入Accordion,因為那時每個Accordion都將具有相同的數據。

有什么想法嗎?

這是我一起扔的東西。 在這里工作的JSFiddle: https ://jsfiddle.net/gkysmsqz/6/

手風琴應保持應顯示手風琴節的活動索引。 您可以克隆每個孩子並在渲染之前向他們添加一些額外的道具(在下面的示例中為activetoggleSection ):

class App extends React.Component {
  render() {
    return (
      <Accordion>
        <AccordionItem title="Question One Title" itemid="question1" openOnLoad onChange={this.updateSelectedItems}>
          <p>here is some text 1</p>
        </AccordionItem>
        <AccordionItem title="Question Two Title" itemid="question2" onChange={this.updateSelectedItems}>
          <p>here is some text 2</p>
        </AccordionItem>
        <AccordionItem title="Question Three Title" itemid="question3" onChange={this.updateSelectedItems}>
          <p>here is some text 3</p>
        </AccordionItem>
      </Accordion>
    );
  }
}

class Accordion extends React.Component {
    state = {
    activeIndex: 0
  };

  toggleSection = index => {
    this.setState({
        activeIndex: index
    });
  };

    render() {
    const rows = this.props.children.map( (child, i) => {
        return React.cloneElement(child, { active: i === this.state.activeIndex, toggleSection: this.toggleSection.bind(this, i) });
    });
    return (
        <div>
          {rows}
        </div>
    );
  }
}

const AccordionItem = props => (
  <div>
    <span onClick={props.toggleSection}>{props.title}</span>
    <div className={props.active ? 'active accordion-item' : 'accordion-item'}>
      {props.children}
    </div>
  </div>
);

我認為您可能會對這篇文章https://reactjs.org/docs/composition-vs-inheritance.html有所幫助。

在您的情況下,您可以在Accordion組件的render方法中執行以下操作:

render() {
  return (
    <div>
    {
      this.props.children.map(
        child => {
          child.passedMethod = this.updateSelectedItems;
          return child;
        }
      )
    }
    </div>
  );
}

如果Accordion跟蹤AccordionItem組件,則應讓Accordion處理AccordionItems的呈現。

App.js

class App extends Component {
  render() {
    return
      <Accordion />;
  }

手風琴

updateItems = () => ...

render() {
  return (
    <div>
            <AccordionItem title="Question One Title" itemid="question1" openOnLoad onChange={this.updateSelectedItems}>
              <p>here is some text 1</p>
            </AccordionItem>
            <AccordionItem title="Question Two Title" itemid="question2" onChange={this.updateSelectedItems}>
              <p>here is some text 2</p>
            </AccordionItem>
            <AccordionItem title="Question Three Title" itemid="question3" onChange={this.updateSelectedItems}>
              <p>here is some text 3</p>
            </AccordionItem>
    </div>
  );
}

按照Reactjs的基礎知識,在Parent(Accordion)中維護您的狀態,並將該狀態傳遞給所有子級(AccordionItem)。 另外,您需要傳遞一個事件處理程序(它將更新父狀態),當選擇任何子項(AccordionItem)時將調用該事件處理程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM