Я думаю, это хорошо иллюстрирует то, что вы пытаетесь сделать:
Помните:
Компонент, представленный <Route>
, всегда может иметь доступ к routeProps
(совпадение, местоположение и история).
Если он отображается с помощью component
prop, как в <Route ... component={Home}/>
, это автоматически.
Если это предоставлено render
реквизитом, вам нужно распространить их, как в:
// You can spread routeProps to make them available to your rendered Component
const FadingRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={routeProps => (
<FadeIn>
<Component {...routeProps}/>
</FadeIn>
)}/>
)
Ссылка на CodeSandbox
Результат:
![enter image description here](https://i.stack.imgur.com/NiClZ.png)
Полный код:
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router } from "react-router-dom";
import AllRoutes from "./AllRoutes";
function App() {
return (
<Router>
<AllRoutes />
</Router>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
AllRoutes.js
import React from "react";
import { Switch, Route } from "react-router-dom";
import Home from "./Home";
import Component1 from "./Component1";
function AllRoutes() {
return (
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/comp1" component={Component1} />
</Switch>
);
}
export default AllRoutes;
Home.js
import React from "react";
import { Link } from "react-router-dom";
function Home(props) {
return (
<div>
I am HOME component
<ul>
<li>
<Link to={"/comp1"}>Component1</Link>
</li>
</ul>
I have access to routeProps: YES
<br />
Because I'm directly rendered from a Route
<ul>
<li>{"props.match:" + props.match.toString()}</li>
<li>{"props.location:" + props.location.toString()}</li>
<li>{"props.history:" + props.history.toString()}</li>
</ul>
</div>
);
}
export default Home;
Component1.js
import React from "react";
import { Link } from "react-router-dom";
import Component1Child from "./Component1Child";
import RouterContext from "./RouterContext";
function Component1(props) {
const routeProps = {
match: props.match,
history: props.history,
location: props.location
};
return (
<RouterContext.Provider value={routeProps}>
<div>
<b>I am Component1</b>
<ul>
<li>
<Link to={"/"}>Home</Link>
</li>
</ul>
I have access to routeProps: YES
<br />
Because I'm directly rendered from a Route.
<br />
And I automatically 'inherit' them when I'm rendered through the Route
'component' prop
<ul>
<li>{"props.match:" + props.match.toString()}</li>
<li>{"props.location:" + props.location.toString()}</li>
<li>{"props.history:" + props.history.toString()}</li>
</ul>
<Component1Child />
</div>
</RouterContext.Provider>
);
}
export default Component1;
Component1Child.js
import React from "react";
import Component1GrandChild from "./Component1GrandChild";
function Component1Child(props) {
return (
<div>
<b>I am Component1Child</b> <br />
<br />
I have access to routeProps: NO
<br />
Because I'm NOT directly rendered from a Route.
<br />I am rendered by Componen1 and routeProps are not automatically
passed down.
<ul>
<li>{"props.match:" + props.match}</li>
<li>{"props.location:" + props.location}</li>
<li>{"props.history:" + props.history}</li>
</ul>
<Component1GrandChild />
</div>
);
}
export default Component1Child;
Component1GrandChild.js
import React from "react";
import useRouteProps from "./useRouteProps";
function Component1GrandChild(props) {
const [match, location, history] = useRouteProps();
return (
<div>
<b>I am Component1GrandChild</b> <br />
<br />
I have access to routeProps: YES
<br />
Because I'm consuming the routeProps provided by Component1 (which is the
one directly rendered by the Route)
<br /> And I'm consuming that through a custom hook called useRouteProps.
<br />I am rendered by Componen1 and routeProps are not automatically
passed down.
<ul>
<li>{"props.match:" + match}</li>
<li>{"props.location:" + location}</li>
<li>{"props.history:" + history}</li>
</ul>
</div>
);
}
export default Component1GrandChild;
RouterContext.js
import React from "react";
const RouterContext = React.createContext(null);
export default RouterContext;
useRouteProps.js
import { useContext } from "react";
import RouterContext from "./RouterContext";
function useRouteProps() {
const routeProps = useContext(RouterContext);
return [routeProps.match, routeProps.location, routeProps.history];
}
export default useRouteProps;