Используя реагирующий маршрутизатор, как я могу передать компонентные реквизиты, используя конфигурацию маршрута? - PullRequest
1 голос
/ 26 марта 2020

Я пытаюсь добиться следующего с помощью одного массива конфигурации маршрутизатора. Здесь следует отметить, что у меня есть переменная состояния storeName, которую я передаю компоненту CategoryPage.

import React, { useState } from 'react'
import { Switch, Route, BrowserRouter } from 'react-router-dom'
import { Navigation } from './Navigation'
import { HomePage } from './HomePage'
import { CategoryPage } from './CategoryPage'
import { ProductPage } from './ProductPage'
import { PageNotFoundPage } from './404Page'

export function App() {
    const [storeName, setStoreName] = useState('My Store')

    return (
        <div>
            <h1>{storeName}</h1>
            <BrowserRouter>
                <Switch>
                    <Route path="/category">
                        <CategoryPage storeName={storeName} />
                    </Route>
                    <Route path="/product">
                        <ProductPage />
                    </Route>
                    <Route path="/" exact>
                        <HomePage />
                    </Route>
                    <Route path="*">
                        <PageNotFoundPage />
                    </Route>
                </Switch>
            </BrowserRouter>
        </div>
    )
}

Если бы мне пришлось переключиться на использование объекта конфигурации маршрута, например, так ...

const routeConfig = [
    {
        path: '/',
        exact: true,
        component: HomePage,
    },
    {
        path: '/category',
        exact: false,
        component: CategoryPage,
    },
    // ...
]

// ...

<Switch>
    {routeConfig.map((route, i) => {
        return (
            <Route
                path={route.path}
                exact={route.exact}
                key={i}
            >
                <route.component />
            </Route>
        )
    })}
</Switch>

... что было бы наиболее подходящим способом передачи реквизита, учитывая, что каждому компоненту могут потребоваться разные реквизиты?

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

Спасибо!


Обновление # 1

Поэтому я попытался вместо этого вернуть компонент из маршрута Конфигурационный массив выглядит так:

const routeConfig = [
    {
        path: '/',
        exact: true,
        component: (props) => <HomePage {...props} />,
    },
    {
        path: '/category',
        exact: false,
        component: (props) => {
            return <CategoryPage {...props} />
        },
    },
]

// ...

const [storeName, setStoreName] = useState('My Store')

// ...

<Switch>
    {routeConfig.map((route, i) => {
        return (
            <Route
                path={route.path}
                exact={route.exact}
                key={i}
            >
                {route.component({ storeName })}
            </Route>
        )
    })}
</Switch>

Это работает, но каждый компонент теперь будет иметь все свойства. Как и в этом случае, мой компонент HomePage не нуждается в storeName пропе, но он все еще есть. Как только я начну добавлять другие компоненты, которым нужны другие переменные состояния, может быть, это может привести к тому, что многие переменные будут храниться в памяти? Это не кажется идеальным.


Обновление # 2

Возможно, я иду в неправильном направлении, используя настройки маршрута. Похоже, что это на самом деле противоположно, чтобы отреагировать на философию маршрутизатора, насколько я понимаю, отсюда https://reacttraining.com/react-router/web/guides/philosophy. Может быть, я остановлюсь на своей первой реализации без конфигурации маршрута, но было бы неплохо узнать, как можно добиться использования конфигурации маршрута и передачи в правильном порядке.

1 Ответ

1 голос
/ 26 марта 2020

В вашем Обновлении # 1 просто извлеките нужные реквизиты

const routeConfig = [
    {
        path: '/',
        exact: true,
        component: () => <HomePage />,
    },
    {
        path: '/category',
        exact: false,
        component: ({storeName}) => {
            return <CategoryPage storeName={storeName} />
        },
    },
]

Или вы можете использовать список релевантных реквизитов для каждого компонента и извлечь их на go

function pickProps(availableProps = {}, selection = []) {
  return selection.reduce(
    (props, selectedProperty) => {
      props[selectedProperty] = availableProps[selectedProperty];
      return props;
    },
    {}
  );
}

// ...

const routeConfig = [{
    path: '/',
    exact: true,
    component: HomePage,
  },
  {
    path: '/category',
    exact: false,
    component: CategoryPage,
    props: ['storeName'],
  },
  // ...
]

// ...
const componentProps = {storeName}
//....
<Switch>
    {routeConfig.map((route, i) => {
        return (
            <Route
                path={route.path}
                exact={route.exact}
                key={i}
            >
                <route.component
                   {...pickProps(componentProps, route.props)}
                />
            </Route>
        )
    })}
</Switch>
...