Currently working on developing an app that utilizes a Django backend and React frontend. The goal is to enable users to log in, receive refresh and access tokens from Django, store the token in local storage, and redirect authenticated users to a static profile page.
Encountering some console errors:
Uncaught TypeError: Cannot read properties of undefined (reading 'getState')
at Provider.js:20:1
at mountMemo (react-dom.development.js:15442:1)
The above error occurred in the <Provider> component:
in Provider (at src/index.js:21)
in Router (at src/index.js:20)
Consider incorporating an error boundary for customized error handling.
Below is my login.js code snippet:
const Login = () => {
const [username, setUserName] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = e => {
e.preventDefault()
try {
const response = AxiosInstance.post('/api/token/',{
username: username,
password: password
});
console.log('from api/token we get this:')
console.log(response)
AxiosInstance.defaults.headers['Authorization'] = "JWT " + response.access;
localStorage.setItem('access_token', response.access);
localStorage.setItem('refresh_token', response.refresh);
console.log('JWT response.access to refresh: ')
return response;
} catch (error) {
throw error;
}
}
Login.propTypes = {
login: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps, {
login
}) (withRouter(Login));
//export default Login;
LoginActions.js excerpt:
export const login = (userData, redirectTo) => dispatch => {
axios
.post("/api/token/", userData)
.then(response => {
const { auth_token } = response.data;
setAxiosAuthToken(auth_token);
dispatch(setToken(auth_token));
dispatch(getCurrentUser(redirectTo));
})
.catch(error => {
dispatch(unsetCurrentUser());
toastOnError(error);
});
};
export const getCurrentUser = redirectTo => dispatch => {
axios
.get("/users/")
.then(response => {
const user = {
username: response.data.username,
email: response.data.email
};
dispatch(setCurrentUser(user, redirectTo));
})
.catch(error => {
dispatch(unsetCurrentUser());
toastOnError(error);
});
};
export const setCurrentUser = (user, redirectTo) => dispatch => {
localStorage.setItem("user", JSON.stringify(user));
dispatch({
type: SET_CURRENT_USER,
payload: user
});
console.log("set user" + redirectTo);
if (redirectTo !== "") {
dispatch(push(redirectTo));
}
};
Reducer.js details:
const createRootReducer = history =>
combineReducers({
router: connectRouter(history),
createUser: signupReducer,
auth: loginReducer
});
export default createRootReducer;
My Root.js implementation:
export default ({ children, initialState = {} }) => {
const history = createBrowserHistory();
const middleware = [thunk, routerMiddleware(history)];
const store = createStore(
rootReducer(history),
initialState,
applyMiddleware(...middleware)
);
// check localStorage
if (!isEmpty(localStorage.getItem("token"))) {
store.dispatch(setToken(localStorage.getItem("token")));
}
if (!isEmpty(localStorage.getItem("user"))) {
const user = JSON.parse(localStorage.getItem("user"));
store.dispatch(setCurrentUser(user, ""));
}
return (
<Provider store={store}>
<ConnectedRouter history={history}>{children}</ConnectedRouter>
</Provider>
);
};
Utils.js content:
export const setAxiosAuthToken = token => {
if (typeof token !== "undefined" && token) {
// Apply for every request
axios.defaults.headers.common["Authorization"] = "Token " + token;
} else {
// Delete auth header
delete axios.defaults.headers.common["Authorization"];
}
};
export const toastOnError = error => {
if (error.response) {
// known error
toast.error(JSON.stringify(error.response.data));
} else if (error.message) {
toast.error(JSON.stringify(error.message));
} else {
toast.error(JSON.stringify(error));
}
};
export const isEmpty = value =>
value === undefined ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0);
Finally, index.js file:
const history = createBrowserHistory();
ReactDOM.render(
<Router history={history}>
<Provider>
<App />
</Provider>
</Router>,
document.getElementById('root')
);
serviceWorker.unregister();
Looking for suggestions or advice on troubleshooting the issues I'm facing!