为noob问题道歉,但我对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移动到手风琴中,因为每个手风琴都会有相同的数据。
思想?
答案 0 :(得分:1)
这是我扔在一起的东西。在这里工作JSFiddle:https://jsfiddle.net/gkysmsqz/6/
Accordion应保持应显示手风琴部分的活动指数。你可以克隆每个孩子并在渲染之前为他们添加一些额外的道具(在下面的例子中为active
和toggleSection
):
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>
);
答案 1 :(得分:0)
我认为您可能会发现这篇文章很有用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>
);
}
答案 2 :(得分:-1)
如果Accordion正在跟踪AccordionItem组件,那么你应该让Accordion处理AccordionItems的渲染。
App.js
class App extends Component {
render() {
return
<Accordion />;
}
Accordion.js
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>
);
}
答案 3 :(得分:-1)
按照Reactjs的基础知识,在Parent(Accordion)中保持你的状态,并将该状态传递给所有的孩子(AccordionItem)。此外,您需要传递一个事件处理程序(将更新父状态),当选择任何子项(AccordionItem)时将调用它。