Реагировать: передавать состояние {this.props.children}

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я создаю веб-приложение, которое сможет отображать некоторые события. Эти события будут отображаться по-разному в зависимости от страницы.

Итак, например, у меня есть компонент EventsNews, в котором я хочу отображать события с помощью пакета Carousel . У меня есть другой компонент, называемый EventsPage, где я хочу отображать события в виде списка. Я хочу повторно использовать код, поэтому я думал о следующем.

     class **EventsNews** extends Component {
        
            render() {
                return (
                    <React.Fragment>
                        <SectionTitleBar>News amp; 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 будут одним из разных способов представления событий и должны получать их от props.

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

export default eventsCards;
 

Моя проблема в том, что при переносе EventsCards внутри событий в компоненте EventsNews я не могу передать состояние из Events в EventsCards.

Я не могу объявлять EventsCards непосредственно внутри компонента Events (вместо {this.props.children}), потому что мне также нужен компонент с именем NewsList, который будет передаваться как дочерние элементы событий внутри другой страницы. Так что в принципе я хочу иметь возможность это сделать.

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

или

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

таким образом, состояние событий всегда будет передаваться его дочерним реквизитам.

Я много читал о вызове дочерних элементов как функции, но я не смог применить что-либо из этого к моей ситуации.

Спасибо.

Ответ №1:

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