我有一个上下文消费者,它的工作方式如下:
<ToastConsumer>
{({ openToast }) => (
<button onClick={() => openToast('You clicked Button A!')}>
Button A
</button>
)}
</ToastConsumer>
但是我想在点击处理程序上添加一些额外的逻辑,并像这样移动openToast Consumer函数:
upVote = () => {
if (!this.state.hasVoted) {
this.setState({
hasVoted: true,
rating: this.state.rating + 1,
});
this.vote(this.state.rating + 1);
}
this.openToast // not working???
};
<ToastConsumer>
{({ openToast }) => (
<div className="vote-button">
<span
className="vote-up vote-action cursor-pointer"
onClick={this.upVote}
>
+1...
为Context API提供的所有示例似乎都是一个简单的单击处理程序,我无法锻炼如何获得像这样的更复杂的示例。
答案 0 :(得分:2)
一种实现此目的的方法是将openToast
函数传递到新的处理程序中。您可以通过将onClick
包装在函数中,或通过简化upVote
函数来做到这一点。
示例:
包装函数:
upVote = (openToast) => {
onClick={() => this.upVote(openToast)}
使用upVote
:
upVote = (openToast) => () => {
onClick={this.upVote(openToast)}
答案 1 :(得分:1)
openToast
需要作为参数提供给upVote
(正如已经提到的另一个答案),upVote
成为高阶函数:
upVote = openToast => () => {
// ...
openToast();
}
并按如下方式使用:
<span onClick={this.upVote(openToast)}>
避免上下文使用方这种复杂性的一种方法是使上下文在类实例中可用。可以使用contextType
:
static contextType = ToastContext;
upVote = openToast => () => {
// ...
this.context.openToast();
}
缺点是,这限制了一个组件只能在一个上下文中使用。
或者可以使用HOC向组件提供上下文:
const withToast = Comp => props => (
<ToastConsumer>
{({ openToast }) => <Comp openToast={openToast} ...props/>}
</ToastConsumer>
);
然后使用withToast(MyComponent)
连接到上下文的组件将以openToast
作为道具:
upVote = openToast => () => {
// ...
this.props.openToast();
}