I am trying to implement react-router in my app. I saw there is now data loading possible within the routing therefore I had to use the createBrowserRouter
. I seem to not fully understand how it is done correctly.
My set up until now was I have a index.tsx file :
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';
import reportWebVitals from './reportWebVitals';
import './index.css';
import {createBrowserRouter, Route, RouterProvider} from 'react-router-dom';
import {ExpressionOverviewPage, expressionLoader} from "./features/expressionoverviewpage/ExpressionOverviewPage";
const container = document.getElementById('root')!;
const root = createRoot(container);
const router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
path: "/",
element: <Route element={<ExpressionOverviewPage />} />
},
{
path: "/:geneID",
element: <ExpressionOverviewPage />,
loader: expressionLoader
}
]
},
]);
root.render(
<React.StrictMode>
<Provider store={store}>
<RouterProvider router={router}>
<App />
</RouterProvider>
</Provider>
</React.StrictMode>
);
reportWebVitals();
In the index.tsx I am calling the file App.tsx:
import React from "react";
import { Amplify, API, graphqlOperation } from "aws-amplify";
import {
ThemeProvider,
Authenticator,
Button,
Flex,
Image,
Text,
useTheme,
View,
} from "@aws-amplify/ui-react";
import aws_exports from "./aws-exports";
import "@aws-amplify/ui-react/styles.css";
import theme from "./theme";
import logo from "./logo.svg";
import { useAppSelector } from "./app/hooks";
import { selectUser } from "./features/auth/authSlice";
import { ErrorPage } from './features/errorpage/ErrorPage';
import {
Routes,
Route,
NavLink,
useSearchParams,
BrowserRouter
} from 'react-router-dom';
import "./styles.css"
import { ExpressionOverviewPage } from "./features/expressionoverviewpage/ExpressionOverviewPage";
import { GeneNameAutoComplete } from "./features/GeneNameAutoComplete/GeneNameAutoComplete"
import { ScoresTable } from "./features/scorestable/ScoresTable";
import { GraphQLQuery } from "@aws-amplify/api";
import { DataPoint, GetViolinDataQuery } from "./API";
import { getViolinData } from "./graphql/queries";
Amplify.configure(aws_exports);
const components = {
Header() {
const { tokens } = useTheme();
return (
<View textAlign="center" padding={tokens.space.large}>
<img src={logo} className="App-logo" alt="logo" width={400} />
</View>
);
}
}
const App = () => {
const store_user = useAppSelector(selectUser);
return (
<ThemeProvider theme={theme}>
<Authenticator
hideSignUp={true}
components={components}
>
{({ signOut, user }) => (
<Flex
direction="column"
justifyContent="space-evenly"
alignItems="flex-start"
alignContent="flex-start"
wrap="nowrap"
gap="1rem"
textAlign="center"
width="100%"
padding="10px"
>
<Flex
direction="row"
justifyContent="space-between"
width="100%"
>
<Image src={logo} alt="logo" width={200} />
{user && (
<View>
<Button onClick={signOut}>
<Text>Sign Out {store_user}</Text>
</Button>
</View>
)}
</Flex>
</Flex>
)}
</Authenticator>
</ThemeProvider>
);
};
export default App;
For this line <Provider store={store}>
in the index.tsx I get following warning:
TS2322: Type '{ children: Element; router: Router; }' is not assignable to type 'IntrinsicAttributes & RouterProviderProps'.
Property 'children' does not exist on type 'IntrinsicAttributes & RouterProviderProps'.
I dont understand what should be the issue there.
The other thing is that I am wondering how I need to change my architecture in order to get createBrowserRouter
running. I think I add the browserRouter at the right place but I think I will have to do something differently with my app.tsx file.
I want to have react-router
working in my app. The goal will be to have an id passed in the url and the loader fetching the data before rendering. I try to get there with baby steps one after the other but already at the beginning I get the warning which I did not expect.
The RouterProvider
takes no children
prop.
declare function RouterProvider( props: RouterProviderProps ): React.ReactElement; interface RouterProviderProps { fallbackElement?: React.ReactNode; router: Router; future?: FutureConfig; }
App
is rendered on one of the routes in router
, so remove it as a child component of RouterProvider
.
const router = createBrowserRouter([
{
path: "/",
element: <App />, // <-- App rendered here
children: [
{
index: true,
element: <Route element={<ExpressionOverviewPage />} />
},
{
path: "/:geneID",
element: <ExpressionOverviewPage />,
loader: expressionLoader
}
]
},
]);
root.render(
<React.StrictMode>
<Provider store={store}>
<RouterProvider router={router} />
</Provider>
</React.StrictMode>
);