I am trying to navigate using history push inside App.jsx.
I have used below code for the same.
componentDidMount() {
if(!this.authService.isAuthenticated())
{
this.props.history.push('/Login');
}
}
But it is giving an error as history is undefined.
I tried logging props object and I got the below output.
Please help me in navigating inside app.jsx.
Export your component with withRouter.
import withRouter.
import { withRouter } from 'react-router'
Export in your component like this.
export default withRouter(MyComponent)//your component name
Related
I am learning about context API and creating an add basket functionality in the Context.js file I have created a context that which will I use for my application it's code is
import React, { createContext } from "react";
const Cart = createContext();
function Context({ childern }) {
return <Cart.Provider>{childern}</Cart.Provider>;
}
export default Context;
now I am wrapping my App component around it in the index.js file
import Context from "./context/Context";
<Context>
<App />
</Context>
but after doing this on the browser it display nothing no error not a single component that I have created is displayed but when I unwrapped the component it works fine
function Context({ props }) {
return <Cart.Provider>{props.childern}</Cart.Provider>;
}
Now it will work. Just add "props" in props and "props.children" in provider.
I am having an axios intercept . It will catch every request . My idea is to dispatch errors commonly in the same place. So i created this intercept. If 404 error came means i will dispatch an action and redirect the page to home. But unfortunately i cant access the props.history in HOC.
Here i am sharing the code of what i have implemented:
HOC axios intercept:
import React, {useEffect} from "react";
import axios from "axios";
const checkRequests= Wrapped => {
function CheckRequests(props) {
useEffect(()=>{
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
switch (error.response.status) {
case 404 :
props.history.push('/login') // will redirect user to login page
break
default :
break
}
// Do something with response error
return Promise.reject(error);
});
})
return (
<Wrapped {...props} />
)
}
return CheckRequests
}
export default checkRequests
And wrapping this component in App.js:
import React from "react"
import CheckRequests from "./HOC/CheckRequests"
function App(props){ ... }
export default checkRequests(App)
Error:
When is console the props in HOC it comes empty
console.log(props) => {}
Please help me with that. Is there any other way to access the history.push from that HOC. For disptaching an action an action am using store.dispatch(logout()).
Wrap the withRouter HOC in the export statement like this:
export default withRouter(checkRequests);
Don't forget to import at the top of the file
import { withRouter } from "react-router";
You may use withRouter
import { withRouter } from 'react-router-dom';
export default withRouter(checkRequests);
Thanks for your answer. I added your suggestion into my code. But i got this error You should not use Route or withRouter() outside a Router . Then i found that it is outside the router so i added this
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
, document.getElementById('root'));
on the index.js . It works fine.
I have a logout function in app (same level as router) that's passed down to various pages so the user can logout from anywhere. How can I add a redirect when the function is called?
I tried using this.props.history.push("/"); but get error Cannot read property 'push' of undefined
To answer to your question we need to know which router you are using and which version.
If you are using react-router you can have a look at https://tylermcginnis.com/react-router-programmatically-navigate/
Use the (withRouter) high-order component
Sample
import React from "react";
import { withRouter } from "react-router-dom";
class App extends React.Component {
...
handleSubmit=()=>{
this.props.history.push("/path");
}
...
}
export default withRouter(App);
Live demo with sample code
In an application using react, redux and react-router, I'm using react-router-redux to issue navigation actions. I found that wrapping routes in a component with connect blocks navigation.
I made a sample with CodeSandbox that illustrates the issue: sample.
As is, the navigation doesn't work. However, if in ./components/Routes.jsx, this line:
export default connect(() => ({}), () => ({}))(Routes);
Is replaced by:
export default Routes;
It works.
Any idea how I could use connect in a component that wraps routes without breaking navigation?
See the troubleshooting section in react-redux docs.
If you change Routes.jsx export to:
export default connect(() => ({}), () => ({}), null, { pure: false })(Routes);
it will work.
This is because connect() implements shouldComponentUpdate by default,
assuming that your component will produce the same results given the
same props and state.
route changes, but props don't so the view doesn't update.
You could achieve same with withRouter hoc.
Not meant to be a duplicate.
I fixed it with withRouter like this
import { withRouter } from 'react-router-dom';
and
export default withRouter( connect(mapStateToProps)(App) );
See Redux, Router integration docs here
Have you ever encountered the warning message:
Warning: You cannot change <Router history>
Well use withRouter from react-router-dom
I have searched for this for so long because the Redux was recreating my App.jsx component which has <Route> </Route> as parents and this warning just freezes the routing in my app. I wanted to have React/Redux component, because I needed to pass authenticated props to the Route component, and redirect base on it, simple.
So import { withRouter } from 'react-router-dom'
and surround your component which is connected to redux with:
export default withRouter(connect(mapStateToProps)(App));
Something more:
Most of the times if you want to communicate with the router, takes some props, pass something else to it, get history, locations form it and you are using Redux in your app, surround this component with withRouter and you will have access to these properties as props.
How can I access browserHistory on redux? I'm passing the browserHistory to a browserRouter from react-router. I want a reducer to listen for an action and the push another url. What's the best solution for this?
First, you'll need to have access to the Route props like history, location, and match in a component. You will have these props automatically if the rendered component was created by a Route component from react-router. Otherwise, you will need to use withRouter from react-router to decorate your component with the Route props.
Example using withRouter:
// MyComponent before
import { connect } from 'react-redux'
const MyComponent = (props) => (<div>{props.message}</div>)
export default connect()(MyComponent)
// MyComponent after
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
const MyComponent = (props) => (<div>{props.message}</div>)
export default withRouter(connect()(MyComponent))
In the after example, MyComponent you will have access to history under props.history (or this.props.history if in a class component).
After you have access to history in your component, you can redirect the app using props.history.push('/a/new/url'). It sounds like you want to use it in an action to change the state. If that's the case, I recommend passing in your reference to history into the action as an argument. Here is an example of an action which creates a new Post and then redirects to a list view of Posts in the same category. Note: I'm using redux-thunk in this example in order to be able to dispatch async actions.
In my PostForm component, I create a variable for history:
const rrHistory = this.props.history
Later, I pass this variable into the createPost action when the Save button is clicked:
createPost(model.title, model.body, model.author, model.category, rrHistory)
Then in the action code, after some async stuff finishes with the API server, we use the rrHistory variable reference to redirect to the categories list view:
rrHistory.push(`/${postCategory}/${newPost.id}`)
Note, that this is a working example, but it is far from perfect. You can also check out this SO Answer for other navigation ideas Programmatically navigate using react router V4
import { withRouter } from 'react-router-dom';
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header));