ReactJS: Как передать функции со ссылкой на другой компонент? - PullRequest
1 голос
/ 05 мая 2020

Я уже несколько дней борюсь с настройкой, которую, как я думал, будет простой и многоразовой:

Я создаю приложение с Ioni c 5 + React , у которого есть своего рода новостная лента, в которой собраны разные типы контента. Но не совсем так, как в Facebook, здесь есть разные разделы для каждого типа контента (например, события, новости и т. Д. c.).

Все они действуют одинаково: у каждого раздела есть заголовок, отображается сначала n элементов, а затем ссылка «Показать еще». Конечно, щелчок по одному из этих элементов немедленно переводит пользователя на страницу с подробностями. Но щелчок по «Показать больше» должен привести пользователя на страницу только с указанным c списком в развернутой форме (вместо, скажем, первых 3 элементов должно быть 50, а при достижении конца этого списка он должен загрузиться следующие 50 и т. д.).

Поскольку API-интерфейсы, доставляющие каждый вид контента, используют разные структуры, страница, на которой встроен этот « компонент раздела », передает две функции, sourceFn и mapFn к этому компоненту. sourceFn обрабатывает загрузку этих n элементов, в то время как mapFn берет элемент и сопоставляет эту структуру данных API с полями, которые необходимы повторно используемому компоненту раздела для отображения элементов списка.

Пока все хорошо, работает. Но я застрял на ссылке "Показать еще". Поскольку здесь этот встроенный раздел перенаправляет на другую страницу, которая динамически отображает расширенный список, необходимо знать соответствующие две функции sourceFn и mapFn. Я пробовал много подходов (например, { ссылка }), но каждый из них не удался. Иногда говорится, что где-то props неизвестно, но в основном из-за DataCloneError: The Object could not be cloned

Я рад каждой подсказке, как это можно сделать (или сделать лучше)


Вот несколько подходов, которые я пробовал: (Пожалуйста, дайте мне знать в комментарии, нужно ли публиковать больше кода. Я не хочу спамить 0 :))

<Link to={'/page/list'+ id} id={id} title={title} sourceFn={sourceFn} mapFn={mapFn}>
    <IonButton slot="end" size="small" fill="clear" routerDirection="forward">
        Show more
        <IonIcon icon={chevronForwardOutline} slot="end" />
    </IonButton>
</Link>
<Link to={{
    pathname: '/page/list'+ id,
    state: {id: id, title: title, sourceFn: sourceFn, mapFn: mapFn}
}}>
    <IonButton slot="end" size="small" fill="clear" routerDirection="forward">
        Show more
        <IonIcon icon={chevronForwardOutline} slot="end" />
    </IonButton>
</Link>

и Route в App.tsx:

<Route
    exact={true}
    path={"/page/list/:sectionid"}
    render={(props) =>
        <List
            id={props.location.state.id}
            title={props.location.state.title}
            sourceFn={props.location.state.sourceFn}
            mapFn={props.location.state.mapFn}
        />}
/>

, а также просто

<Route exact={true} path={"/page/list/:sectionid"} component={List} />

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Я думаю, это вызывает Context .

Родительский компонент может иметь контекст на уровне, где sourceFn и mapFn происходят из :

const SomeContext = React.createContext()

export const useContextName = React.useContext(SomeContext)

<SomeContext.Provider value={{ sourceFn, mapFn }}>
  ...your routes here...
</SomeContext.Provider>

тогда в вашем компоненте List вы можете сделать:

import { useContextName } from 'wherever/you/are/exporting/from'

const List = (...your props ...) => {
   const { sourceFn, mapFn } = useContextName()
   ... the rest of your component ...
}

и, как вы сказали, ваш маршрут будет просто:

<Route exact={true} path={"/page/list/:sectionid"} component={List} />
0 голосов
/ 05 мая 2020

Я бы предложил подход React.Context, но вы также можете просто передать имена функций в качестве имен параметров, как это

<Route exact={true} 
  path={"/page/list/:mapFuncName/:sourceFuncName/:sectionid"} 
  component={List} />

В вашей вспомогательной библиотеке функций отображаются все функции, чтобы они могли быть доступ осуществляется по указанному c имени.

mapFuncMap : {
  func1 : ()=> {}
  func2 : ()=> {}
  func3 : ()=> {}
}

sourceFuncMap : {
  func1 : ()=> {}
  func2 : ()=> {}
  func3 : ()=> {}
}

тогда, когда вам нужна функция, вы можете использовать имя функции для доступа к ней на карте функций

sourceFuncMap['func1']();
...