Я пытаюсь реализовать как Redux, так и React-Router в проекте блога React, в котором я получаю данные из API и сохраняю их в Redux, однако они не отображаются и ошибок не возникает.
Я попробовал следующий код в своем App.jsx
const getRouter = (store) => {
return (
createBrowserRouter(
createRoutesFromElements(
<Route path = "/" element = {<Layout />}>
<Route
index
element = {<PostList />}
errorElement = {<Error />}
loader = {(arg) => {
arg.post = store.getState().posts
}}
/>
<Route path='/posts' element = {<PostForm />}>
<Route />
</Route>
<Route path = "*" element = {<NotFound />} />
</Route>
)
)
)
}
export default function App() {
<Provider store = {store}>
<RouterProvider router = {getRouter(store)} />
</Provider>
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Функция загрузчика маршрута принимает один объект аргумента со свойствами params и request. arg.post не определено.
Компонент App также должен вернуть JSX, который он собирается отобразить.
Если вам нужно получить доступ к контексту хранилища Redux в загрузчике маршрутов, я бы предложил просто импортировать store и получить доступ непосредственно в функции загрузчика вместо закрытия экземпляра хранилища в маршрутизаторе. Проблема с имеющимся у вас кодом заключается в том, что он будет создавать новый маршрутизатор каждый раз, когда обновляется магазин и выполняется повторная отрисовка компонента Provider.
Пример:
const router = createBrowserRouter(
createRoutesFromElements(
<Route element = {<Layout />}>
<Route
path = "/"
element = {<PostList />}
errorElement = {<Error />}
loader = {({ params, request }) => {
const { posts } = store.getState();
// return some value to `PostList` component
}}
/>
<Route path='/posts' element = {<PostForm />}>
...
</Route>
<Route path = "*" element = {<NotFound />} />
</Route>
)
)
export default function App() {
return (
<Provider store = {store}>
<RouterProvider router = {router} />
</Provider>
);
}
Если вы действительно хотите по-прежнему использовать функцию для получения маршрутизатора, то хотя бы запомните маршрутизатор, чтобы он предоставлялся как стабильная ссылка и не создавался заново каждый раз при App или Provider повторном рендеринге.
export default function App() {
const router = React.useMemo(() => getRouter(store), [store]);
return (
<Provider store = {store}>
<RouterProvider router = {router} />
</Provider>
);
}
Если вам не нужно использовать загрузчик маршрутов, кроме как для доступа и возврата значения хранилища, есть лучшие альтернативы. Вы можете просто использовать хуки useDispatch и useSelector, экспортированные из react-redux, в компонентах, которым необходимо подписаться на обновления состояния.
Пример:
...
import { useSelector } from 'react-redux';
...
const PostList = () => {
const posts = useSelector(state => state.posts);
...
};
const router = createBrowserRouter(
createRoutesFromElements(
<Route element = {<Layout />}>
<Route
path = "/"
element = {<PostList />}
errorElement = {<Error />}
/>
<Route path='/posts' element = {<PostForm />}>
...
</Route>
<Route path = "*" element = {<NotFound />} />
</Route>
)
)
export default function App() {
return (
<Provider store = {store}>
<RouterProvider router = {router} />
</Provider>
);
}
Основное преимущество использования перехватчика useSelector заключается в том, что это подписка: при обновлении выбранного состояния подписанные компоненты будут запускаться для повторной визуализации с текущим значением состояния. Это не тот случай, когда используется store.getState, он получает текущее значение только один раз, в момент вызова getState, и не подписывается на будущие изменения.
@ user20984108 Если вам вообще не нужна функция загрузчика, просто используйте хуки useDispatch и useSelector в своих компонентах, чтобы получить доступ к функции dispatch и выбрать состояние из хранилища. Вам не нужно использовать функцию для создания объекта router, см. мой первый пример. Если внешних зависимостей нет, просто объявите router вне ReactTree, чтобы это была стабильная ссылка (например, созданная один раз и являющаяся одной и той же ссылкой на протяжении всего существования экземпляра приложения). Имеет ли все это смысл? Вам нужно рассматривать это как примеры?
Было бы более полезно, если бы я мог видеть их в качестве примера.
есть ли другой способ получить доступ к хранилищу без функции загрузчика? и какой еще способ получить доступ к роутеру без использования функции