我有一个由4个相互关联的组件构成的生态系统,如果我可以从另一个组件中操纵一个组件的状态,它将非常有用。
这是我的MidSection组件:
import React, {Component} from 'react';
import {render} from 'react-dom';
import $ from 'jquery';
import List from './List';
import OpenSessionCard from './OpenSessionCard';
class MidSection extends Component {
constructor() {
super(...arguments);
this.state = {
cardsToBeDisplayed: this.props.sessionCards,
cardsFilter: 'All',
cardExpanded: false,
cardToBeDisplayed: null
};
}
filterCards() {
let selectedValue = $('#cards-filter').val();
if (selectedValue === 'All') {
this.setState({
cardsToBeDisplayed: this.props.sessionCards,
cardsFilter: 'All',
cardExpanded: false,
cardToBeDisplayed: null
});
} else {
this.setState({
cardsToBeDisplayed: this.props.sessionCards.filter((sessionCard) => sessionCard.status === selectedValue),
cardsFilter: selectedValue,
cardExpanded: false,
cardToBeDisplayed: null
});
}
}
render() {
let cardList, openSessionCard;
if (!this.state.cardToBeDisplayed) {
cardList = (
<List cards={this.state.cardsToBeDisplayed} filter={this.state.cardsFilter}/>
);
} else {
openSessionCard = (
<OpenSessionCard card={this.state.cardToBeDisplayed}/>
);
};
return (
<section className="col-md-8 col-sm-12 col-xs-12 middle-section-container">
<div className="nav-justified pull-left">
<div className="gray-background-color col-xs-12 form-control-static">
<div className="col-xs-6">
<label className="control-label green-color" htmlFor="inputError1">MY SESSIONS</label>
</div>
<div className="col-xs-2 col-xs-offset-4 text-right">
<select id="cards-filter" className="form-control" onChange={this.filterCards.bind(this)}>
<option>All</option>
<option>Open</option>
<option>Scheduled</option>
<option>Completed</option>
<option>Closed</option>
</select>
</div>
</div>
{cardList}
{openSessionCard}
</div>
</section>
);
}
componentDidMount() {
$('#mid-section').attr('data-rendered', 'true');
}
}
export default MidSection;
这是我的SessionCard组件:
import React, {Component} from 'react';
import {render} from 'react-dom';
import $ from 'jquery';
import MidSection from './MidSection';
class SessionCard extends Component {
openCard() {
/*************
MidSection.setState({
cardsToBeDisplayed: null,
cardsFilter: null,
cardExpanded: true,
cardToBeDisplayed: this
});
**************/
$('#cards-filter').attr('disabled', 'disabled');
}
render() {
return (
<div className="card" onClick={this.openCard.bind(this)}>
<div className="card__title green-color">{this.props.name}</div>
<div className="card__details">
<span>Facilitator: {this.props.facilitator}</span><br/>
<span>Mode: {this.props.mode}</span><br/>
<span>Status: {this.props.status}</span><br/>
</div>
</div>
);
}
}
export default SessionCard;
我希望SessionCard组件中的openCard()函数调用MidSection组件的setState()函数。有什么办法可以实现吗?如何从SessionCard组件中引用MidSection组件(及其当前状态)?
答案 0 :(得分:3)
您应该只从主(父)组件设置状态。所有儿童成分应该是“愚蠢的”#34;组件。传入你想要调用的功能,如SessionCard的支柱,如:
<OpenSessionCard card={this.state.cardToBeDisplayed} setStateFunc={this.setStateFunc}/>
然后在你的openCard()函数调用中:
this.props.setStateFunc();
这将调用父组件中的函数,并允许您从那里操作状态。
答案 1 :(得分:0)
非常感谢@ erichardson30!尽管你的解决方案并不完全足够,但它引导我走上了正确的轨道。将setState()函数作为prop传递只传递了函数,没有上下文(读取:应该调用它的组件)。所以,我将对MidSection组件本身的引用作为prop传递,然后在openCard()函数中,我在其props中调用了组件的setState()函数。
在我的MidSection组件中:
<OpenSessionCard card={this.state.cardToBeDisplayed} midSectionComponent={this}/>
在我的openCard()函数中:
let midSectionComponent = this.props.midSectionComponent;
midSectionComponent.setState({
cardsToBeDisplayed: null,
cardsFilter: null,
cardExpanded: true,
cardToBeDisplayed: this
});
它的工作方式与我想要的完全一致。再次感谢! :)