I m using react and i have app.js like this:
function App() {
const [data, setData] = useState([]);
useEffect(() => { ... setData([1,2,3]);}, []);
return (
<Router>
<Routes>
<Route element={<SomeElement/>}>
<Route index exact path="/path1" element={<SomeComponent data={data}/>}/>
<Route path="/path2" element={<AnotherComponent data={data}/>}/>
</Routes>
<Router/>);
}
I just want to move routes, which are using data to separate component, since i want to load data only if i need.
I would like to see something like this:
function SeparateRoutes(){
const [data, setData] = useState([]);
useEffect(() => { ... setData([1,2,3]);}, []);
return <Fragment>
<Route index exact path="/" element={<SomeComponent data={data}/>}/>
<Route path="/path" element={<AnotherComponent data={data}/>}/> </Fragment>;
}
function App() {
return (
<Router>
<Routes>
<SeparateRoutes/>
<Route index exact path="/" element={<SomeComponent data={data}/>}/>
<Route path="/path" element={<AnotherComponent data={data}/>}/>
</Routes>
<Router/>);
}
I`ve tried this variant but there is an error: component children must be a Route or React.Fragment
>Solution :
If you are just trying to split the code up a bit and render routes separately in components then each set of Route components need to be rendered in a Routes component.
Example:
import { Routes, Route } from 'react-router-dom';
function SeparateRoutes() {
const [data, setData] = useState([]);
useEffect(() => {
...
setData([1, 2, 3]);
}, []);
return (
<Routes>
<Route path="/path1" element={<SomeComponent data={data} />} />
<Route path="/path2" element={<AnotherComponent data={data} />} />
</Routes>
);
}
Make sure you aren’t accidentally rendering a self-closed Router component tag, it should wrap all the routes and UI content that needs to access the routing context it provides.
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<SeparateRoutes />
<Routes>
<Route path="/" element={<SomeComponent />} />
<Route path="/path" element={<AnotherComponent />} />
</Routes>
</Router>
);
}
If you only want data to be fetched for specific routes you might also try creating a layout route and rendering nested routes instead of an entirely separate component with descendent routes.
Example:
import { Outlet } from 'react-router-dom';
function DataLayout() {
const [data, setData] = useState([]);
useEffect(() => {
...
setData([1, 2, 3]);
}, []);
// Pass data state in Outlet context
return <Outlet context={data} />;
}
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<SomeComponent />} />
<Route path="/path" element={<AnotherComponent />} />
<Route element={<DataLayout />}>
<Route path="/path1" element={<SomeComponent />} />
<Route path="/path2" element={<AnotherComponent />} />
</Route>
</Routes>
</Router>
);
}
import { useOutletContext } from 'react-router-dom';
export const AnotherComponent = () => {
const data = useOutletContext();
...
};