反应:将状态传递给 {this.props.children}

时间:2021-02-09 21:27:17

标签: javascript reactjs

我正在构建一个能够显示一些事件的 Web 应用程序。这些事件将根据页面以不同的方式显示。

例如,我有一个名为 EventsNews 的组件,我想在其中使用 Carousel 包显示事件。我有另一个名为 EventsPage 的组件,我想在其中以列表的形式显示事件。我想重用代码,所以我在考虑做下一个。

    class **EventsNews** extends Component {
        
            render() {
                return (
                    <React.Fragment>
                        <SectionTitleBar>News & Events</SectionTitleBar>
                        <h1 className={classes.Title}>Latest Events</h1>
        
                        **<Events>
                            <EventsCards />
                        </Events>**
                        
                        <SeeMoreButton href="/">See All Events {'>'}</SeeMoreButton>
                    </React.Fragment>
                );
            }
    }
export default EventsNews;

然后,我的事件组件将处理与状态和 HTTP 处理相关的所有内容(从 API 中使用。然后该组件应将状态传递给 {this.props.children}。

class **Events** extends Component {

    **state** = {
        events: [
            {id: "1", title: "...", local: "...", date: "...", description: "...", url: "Link1"},
            {id: "2", title: "...", local: "...", date: "...", description: "...", url: "Link2"},
            {id: "3", title: "...", local: "...", date: "...", description: "...", url: "Link3"},
        ]
    }

    // TODO: HTTP Handling...

    render() {

        return (
            <React.Fragment>
                **{this.props.children(this.state.events)}**
            </React.Fragment>
        );
    }
}

export default Events;

那么我的 EventsCards 将是呈现事件的不同方式之一,应该从道具中接收它们。

const **eventsCards** = (props) => (
   
    <Carousel>
        {this.props.events.map( item => (
            <CustomCard title={item.title} subtitle={item.date} body={item.description}/>
        ))}
    </Carousel>
);

export default eventsCards;

我的问题是,在 EventsNews 组件中将 EventsCards 包装在 Events 内时,我无法将状态从 Events 传递到 EventsCards。

我不能直接在 Events 组件内声明 EventsCards(而不是 {this.props.children}),因为我还需要有一个名为 NewsList 的组件,它将作为 Events 的子级在其他页面中传递。所以基本上我希望能够做到这一点。

<Events>
     <EventsCards /> //display the events in cards.
</Events>

<Events>
 <EventsList /> //display the events in a list.
</Events>

以某种方式将事件状态始终传递给它的子道具。

我已经阅读了很多关于将孩子作为函数调用的内容,但我无法将其中的任何内容应用于我的情况。

谢谢。

1 个答案:

答案 0 :(得分:0)

children prop 不是函数,因此您无法调用它。相反,您必须使用以下实用程序:

return React.cloneElement(React.Children.only(children), { events }));

让我们现在通过它。 Children.only 检查给定值是否只包含一个 React 元素。接下来我们克隆返回的元素并更新它的 props 以包含 events。如果要修改多个子项,则应使用 Children.map

要了解有关此类实用函数的更多信息,请参阅:https://reactjs.org/docs/react-api.html#reactchildren