react-router - pass props to handler component
UPDATE
Since new release, it's possible to pass props directly via the Route
component, without using a Wrapper. For example, by using render
prop.
Component:
class Greeting extends React.Component {
render() {
const {text, match: {params}} = this.props;
const {name} = params;
return (
<React.Fragment>
<h1>Greeting page</h1>
<p>
{text} {name}
</p>
</React.Fragment>
);
}
}
Usage:
<Route path="/greeting/:name" render={(props) => <Greeting text="Hello, " {...props} />} />
Codesandbox Example
OLD VERSION
My preferred way is wrap the Comments
component and pass the wrapper as a route handler.
This is your example with changes applied:
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var CommentsWrapper = React.createClass({
render: function () {
return (
<Comments myprop="myvalue"/>
);
}
});
var Index = React.createClass({
render: function () {
return (
<div>
<header>Some header</header>
<RouteHandler/>
</div>
);
}
});
var routes = (
<Route path="/" handler={Index}>
<Route path="comments" handler={CommentsWrapper}/>
<DefaultRoute handler={Dashboard}/>
</Route>
);
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
How to pass props within components with react-router v6
When you send state in the route transition it isn't sent via props, but rather it's sent via the routing context. In the EditUser
component you can access the sent route state via the location
object returned from the useLocation
hook.
Example:
import { useLocation } from 'react-router-dom';
...
const location = useLocation();
const { state } = location;
const { user } = state || {};
React router v6 access route params and pass as props
I don't want to put
useParams()
in the component because this
tightly couples it to the URL. For example, what if I wanted to render
another ProfileComponent elsewhere, with a different username to that
in the URL. It seems to violate best practice for unit testing unless
I can do it like my example.
Any route using a username
route match param would still be accessible via the useParams
hook, but I think I understand what you are after. If I understand your question correctly you are asking how to map a route match param to a component prop in a generic way.
For this you can simply use a wrapper component to "sip" the route match param and pass it along to your component on any specific prop.
const ProfileComponentWrapper = () => {
const { username } = useParams();
return <ProfileComponent username={username} />;
};
...
<Route
path='/u/:username/'
element={<ProfileComponentWrapper />}
/>
How to pass props to Route component?
The solution is already in your code, the props may vary a little bit, depending on your requirements
<Route
path="/dashboard"
render={props => <Dashboard isActive={isActive} handleClick={handleClick} {...props} />} />
Can't figure out how to pass props to components when using React Router v5 and Redux
To pass your props to your component use render prop
, also you should change your routes to start with /movies, otherwise, your components will not work.
function Movies() {
return (
<Switch>
<Route
path="/movies"
exact
render={() => (
<MediaGridContainer class_name="movies" scope="popular" />
)}
/>
<Route
path="/movies/trending"
render={() => (
<MediaGridContainer class_name="movies" scope="trending" />
)}
/>
<Route
path="/movies/disliked"
render={() => (
<MediaGridContainer class_name="movies" scope="disliked" />
)}
/>
</Switch>
);
}
Passing props from outlet to parent using React Router 6
You can't pass props, per se, but you can provide a context value to the Outlet
that App
is rendering that the routed components can access via the useOutletContext
hook.
Example:
const AppLayout = () => {
const [title, setTitle] = useState("");
return (
<>
<h1>App: {title}</h1>
<Outlet context={{ setTitle }} /> // <-- provide context value
</>
)
};
const BleTable = ({ title }) => {
const { setTitle } = useOutletContext(); // <-- access context value
return (
<>
<h1>BleTable</h1>
<button type="button" onClick={() => setTitle(title)}>Update App Title</button>
</>
);
}
...
<BrowserRouter>
<Routes>
<Route path="/" element={<AppLayout />}>
<Route path="ble" element={<BleTable title="Bluetooth" />} />
<Route path="create-user" element={<UserForm/>}/>
</Route>
</Routes>
</BrowserRouter>
Related Topics
Parse Date Without Timezone JavaScript
What's the Difference Between & and && in JavaScript
What's the Fastest Way to Loop Through an Array in JavaScript
Why Is 'Replace' Property Deprecated in Angularjs Directives
How to Dynamically Create '@-Keyframe' CSS Animations
Refresh a Div That Has a Google Ad Inside It
What HTML Tags Support the Onload/Onerror JavaScript Event Attributes
Prevent Form Submission with Enter Key
Why My Show Hide Button Needs Double-Click on First Time
Emailing Google Sheet Range (With or Without Formatting) as a HTML Table in a Gmail Message
Are Variable Operators Possible
Prevent a Webpage from Navigating Away Using JavaScript
Redirect Parent Window from an Iframe Action
Is This an Example of Variable Shadowing in JavaScript
Scope of Sessionstorage and Localstorage
Error: Failed to Execute 'Appendchild' on 'Node': Parameter 1 Is Not of Type 'Node'
How Send a Form with JavaScript When Input Name Is "Submit"
How to Detect a Long Touch Pressure with JavaScript for Android and Iphone