I have a React component that takes in username and password and sends it for authentication. If authentication is successful, the page should move to a different route which renders another component.
Now the problem is, I am not sure how I can change route from my store? i.e. without using the <Link>
component of React Router? I know that we can use this.props.history.push(/url)
to change route programatically, but it can only be used inside a React Component using <Route>
, not from the store.
I am using React16 with MobX for state management, and ReactRouter V4 for routing.
Store:
class Store {
handleSubmit = (username, password) => {
const result = validateUser(username, password);
// if result === true, change route to '/search' to render Search component
}
}
Login Component:
const Login = observer(({ store }) => {
return (
<div>
<form onSubmit={store.handleSubmit}>
<label htmlFor="username">User Name</label>
<input type="text" id="username" onChange={e => store.updateUsername(e)} value={store.username} />
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={e => store.updatePassword(e)} value={store.password} />
<input type="submit" value="Submit" disabled={store.disableSearch} />
</form>}
</div>
)
})
Main App Component:
import { Router, Route, Link } from "react-router-dom";
@observer
class App extends React.Component {
render() {
return (
<Router history={history}>
<div>
<Route exact path="/"
component={() => <Login store={store} />}
/>
<Route path="/search"
component={() => <Search store={store} />}
/>
</div>
</Router>
)
}
}
Use the Navigate element to set a default route with redirect in React Router, e.g. <Route path="/" element={<Navigate to="/dashboard" />} /> . The Navigate element changes the current location when it is rendered. Copied!
Connected React Router is a Redux binding for React Router v4 and v5. It synchronizes router state with Redux store via a unidirectional flow and uses react-hot-loader to facilitate hot reloading of functional components while preserving state.
Since v4 of React Router, there are three approaches that you can take to programmatic routing within components. Use the withRouter higher-order component. Use the context .
You could create the history
in a separate module, and import that both in your main app Component and Store:
// history.js
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
export default history;
// Store.js
import history from './history';
class Store {
handleSubmit = (username, password) => {
const result = validateUser(username, password);
if (result) {
history.push('/search');
}
}
}
// App.js
import { Router, Route, Link } from "react-router-dom";
import history from './history';
@observer
class App extends React.Component {
render() {
return (
<Router history={history}>
<div>
<Route exact path="/"
component={() => <Login store={store} />}
/>
<Route path="/search"
component={() => <Search store={store} />}
/>
</div>
</Router>
)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With