Reputation: 875
I have a userContext that is authenticating the user. It is working, but after successful login I want the user to be directed to the /dashboard. so I'm using this.props.history.push('/dashboard'); but I'm getting the below error.
TypeError: Cannot read property 'props' of undefined
Is there a better way to do this? While using a function?
UserContext.js
import React, {useState, createContext, useEffect} from 'react'
import Firebase from 'firebase'
import { Redirect } from 'react-router'
export const UserContext = createContext();
export const UserProvider = props => {
const [user, setUser] = useState({
username: "blank",
loggendIn: false
});
var id = localStorage.getItem('id');
// check if its null
console.log(id);
useEffect(() => {
if (id != null) {
console.log('id is there');
// load user from realtime database
const dbOBJ = Firebase.database().ref().child("users").child(id);
dbOBJ.on('value', function(snapshot) {
setUser(snapshot.val());
});
} else {
console.log('no id :( ');
}
console.log(props.history);
this.props.history.push('/dashboard');
}, [id]);
return (
<UserContext.Provider value = {[user, setUser]} >
{ props.children}
</UserContext.Provider>
);
}
app.js
import React from 'react';
import NavBar from './components/navBar';
import Login from './components/login';
import Session from './components/session';
import Dashboard from './components/dashboard';
import './App.css';
import Container from '@material-ui/core/Container';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom';
import { UserProvider } from './model/UserContext'
function App() {
return (
<div>
<UserProvider>
<Session />
<NavBar />
<Container maxWidth="sm">
<Router>
<Route path='/Login' component={Login} />
<Route path='/Dashboard' component={Dashboard} />
</Router>
</Container>
</UserProvider>
</div>
);
}
export default App;
Upvotes: 0
Views: 214
Reputation: 202836
That is a functional component, there is no instance for this
to exist on, history would just be on props
. You also probably need to "inject" the router's history object into props as well.
import React, {useState, createContext, useEffect} from 'react'
import Firebase from 'firebase'
import { Redirect, withRouter } from 'react-router'
export const UserContext = createContext();
const UserProvider = ({ // don't export here
children, // destructuring props here so it is clearer
history
}) => {
const [user, setUser] = useState({
username: "blank",
loggendIn: false
});
var id = localStorage.getItem('id');
// check if its null
console.log(id);
useEffect(() => {
if (id != null) {
console.log('id is there');
// load user from realtime database
const dbOBJ = Firebase.database().ref().child("users").child(id);
dbOBJ.on('value', function(snapshot) {
setUser(snapshot.val());
});
} else {
console.log('no id :( ');
}
console.log(props.history);
history.push('/dashboard'); // <-- no this.props, just props or destructured props
}, [id]);
return (
<UserContext.Provider value = {[user, setUser]} >
{ children }
</UserContext.Provider>
);
}
export default withRouter(UserProvider);
Upvotes: 1
Reputation: 15555
I think you're mixing up multiple thing:
Fat arrow functions don't have a this
on it defined it'll pick up window
as this for your code.
window.name = 'Mamba';
(() => {console.log(this.name)})();
So you need to use the props directly here like this:
this.props.history.push('/dashboard');
=> props.history.push('/dashboard');
You might like to go through this question if you're still unsuccessful
Upvotes: 0