I am building a react application with Django rest framework (Djoser) for athentication. Now to manage authentication I am using react redx. bt somehow getting this error when passing stattoprops using connect method. not sre where exactly the error is.
Here are my files:
Reducer Atyh file:
import {
LOGIN_SUCCESS,
LOGIN_FAIL,
USER_LOADED_SUCCESS,
USER_LOADED_FAIL,
AUTHENTICATED_SUCCESS,
AUTHENTICATED_FAIL,
PASSWORD_RESET_SUCCESS,
PASSWORD_RESET_FAIL,
PASSWORD_RESET_CONFIRM_SUCCESS,
PASSWORD_RESET_CONFIRM_FAIL,
SIGNUP_SUCCESS,
SIGNUP_FAIL,
ACTIVATION_SUCCESS,
ACTIVATION_FAIL,
GOOGLE_AUTH_SUCCESS,
GOOGLE_AUTH_FAIL,
FACEBOOK_AUTH_SUCCESS,
FACEBOOK_AUTH_FAIL,
LOGOUT
} from '../Actions/Types';
const initialState = {
access: localStorage.getItem('access'),
refresh: localStorage.getItem('refresh'),
isAuthenticated: false,
user: null
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch(type) {
case AUTHENTICATED_SUCCESS:
return {
...state,
isAuthenticated: true
}
case LOGIN_SUCCESS:
case GOOGLE_AUTH_SUCCESS:
case FACEBOOK_AUTH_SUCCESS:
localStorage.setItem('access', payload.access);
localStorage.setItem('refresh', payload.refresh);
return {
...state,
isAuthenticated: true,
access: payload.access,
refresh: payload.refresh
}
case SIGNUP_SUCCESS:
return {
...state,
isAuthenticated: false
}
case USER_LOADED_SUCCESS:
return {
...state,
user: payload
}
case AUTHENTICATED_FAIL:
return {
...state,
isAuthenticated: false
}
case USER_LOADED_FAIL:
return {
...state,
user: null,
}
case GOOGLE_AUTH_FAIL:
case FACEBOOK_AUTH_FAIL:
case LOGIN_FAIL:
case SIGNUP_FAIL:
case LOGOUT:
localStorage.removeItem('access');
localStorage.removeItem('refresh');
return {
...state,
access: null,
refresh: null,
isAuthenticated: false,
user: null,
error:payload.detail
}
case PASSWORD_RESET_SUCCESS:
case PASSWORD_RESET_FAIL:
case PASSWORD_RESET_CONFIRM_SUCCESS:
case PASSWORD_RESET_CONFIRM_FAIL:
case ACTIVATION_SUCCESS:
case ACTIVATION_FAIL:
return {
...state
}
default:
return state
}}
Action Auth file:
import axios from 'axios';
import {
LOGIN_SUCCESS,
LOGIN_FAIL,
USER_LOADED_SUCCESS,
USER_LOADED_FAIL,
AUTHENTICATED_SUCCESS,
AUTHENTICATED_FAIL,
PASSWORD_RESET_SUCCESS,
PASSWORD_RESET_FAIL,
PASSWORD_RESET_CONFIRM_SUCCESS,
PASSWORD_RESET_CONFIRM_FAIL,
SIGNUP_SUCCESS,
SIGNUP_FAIL,
ACTIVATION_SUCCESS,
ACTIVATION_FAIL,
GOOGLE_AUTH_SUCCESS,
GOOGLE_AUTH_FAIL,
FACEBOOK_AUTH_SUCCESS,
FACEBOOK_AUTH_FAIL,
LOGOUT
} from './Types';
export const load_user = () => async dispatch => {
if (localStorage.getItem('access')) {
const config = {
headers: {
'Content-Type': 'application/json',
'Authorization': `JWT ${localStorage.getItem('access')}`,
'Accept': 'application/json'
}
};
try {
const res = await axios.get(`${process.env.REACT_APP_API_URL}/auth/users/me/`, config);
dispatch({
type: USER_LOADED_SUCCESS,
payload: res.data
});
} catch (err) {
dispatch({
type: USER_LOADED_FAIL
});
}
} else {
dispatch({
type: USER_LOADED_FAIL
});
}
};
export const googleAuthenticate = (state, code) => async dispatch => {
if (state && code && !localStorage.getItem('access')) {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
const details = {
'state': state,
'code': code
};
const formBody = Object.keys(details).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(details[key])).join('&');
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/o/google-oauth2/?${formBody}`, config);
dispatch({
type: GOOGLE_AUTH_SUCCESS,
payload: res.data
});
dispatch(load_user());
} catch (err) {
dispatch({
type: GOOGLE_AUTH_FAIL
});
}
}
};
export const checkAuthenticated = () => async dispatch => {
if (localStorage.getItem('access')) {
const config = {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
};
const body = JSON.stringify({ token: localStorage.getItem('access') });
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/jwt/verify/`, body, config)
if (res.data.code !== 'token_not_valid') {
dispatch({
type: AUTHENTICATED_SUCCESS
});
} else {
dispatch({
type: AUTHENTICATED_FAIL
});
}
} catch (err) {
dispatch({
type: AUTHENTICATED_FAIL
});
}
} else {
dispatch({
type: AUTHENTICATED_FAIL
});
}
};
export const login = (email, password) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ email, password });
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/jwt/create/`, body, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
});
dispatch(load_user());
} catch (err) {
dispatch({
type: LOGIN_FAIL
})
}
};
export const signup = (first_name, last_name, email, password, re_password) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ first_name, last_name, email, password, re_password });
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/users/`, body, config);
dispatch({
type: SIGNUP_SUCCESS,
payload: res.data
});
} catch (err) {
dispatch({
type: SIGNUP_FAIL
})
}
};
export const verify = (uid, token) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ uid, token });
try {
await axios.post(`${process.env.REACT_APP_API_URL}/auth/users/activation/`, body, config);
dispatch({
type: ACTIVATION_SUCCESS,
});
} catch (err) {
dispatch({
type: ACTIVATION_FAIL
})
}
};
export const reset_password = (email) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ email });
try {
await axios.post(`${process.env.REACT_APP_API_URL}/auth/users/reset_password/`, body, config);
dispatch({
type: PASSWORD_RESET_SUCCESS
});
} catch (err) {
dispatch({
type: PASSWORD_RESET_FAIL
});
}
};
export const reset_password_confirm = (uid, token, new_password, re_new_password) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({ uid, token, new_password, re_new_password });
try {
await axios.post(`${process.env.REACT_APP_API_URL}/auth/users/reset_password_confirm/`, body, config);
dispatch({
type: PASSWORD_RESET_CONFIRM_SUCCESS
});
} catch (err) {
dispatch({
type: PASSWORD_RESET_CONFIRM_FAIL
});
}
};
export const logout = () => dispatch => {
dispatch({
type: LOGOUT
});
};
Store.js
import { createStore, applyMiddleware, compose } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from './Reducers/Index';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
login screen:
import * as React from "react";
import { useState } from "react";
import { redirect, Link as routerLink } from "react-router-dom";
import { connect } from "react-redux";
import { login } from "../Redux/Actions/Auth";
import CButton from "../components/Button";
import Visibility from "@mui/icons-material/Visibility";
import VisibilityOff from "@mui/icons-material/VisibilityOff";
import Box from "@mui/material/Box";
import {
Typography,
TextField,
Link,
Container,
IconButton,
InputAdornment,
Divider,
Button,
} from "@mui/material";
const Login = ({ login, isAuthenticated }) => {
const [showPassword, setShowPassword] = React.useState(false);
const handleClickShowPassword = () => setShowPassword((show) => !show);
const handleMouseDownPassword = (event) => {
event.preventDefault();
};
const [formData, setFormData] = useState({
email: "",
password: "",
});
const [formError, setFormError] = useState({});
const [Validated, setValidated] = useState(false);
const { email, password } = formData;
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = (e) => {
e.preventDefault();
setFormError(validate(formData));
if(Validated === true){
login(email, password);
}
};
const validate = (values) => {
const Errors = {};
const EmailRegrex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,}$/i;
if (!values.email) {
Errors.email = "Email is Required";
} else if (!EmailRegrex.test(values.email)) {
Errors.email = "Email address is not valid";
}
if (!values.password) {
Errors.password = "Password is Required";
}
setValidated(true)
return Errors;
};
if (isAuthenticated) {
return redirect("/");
}else{
console.log(typeof(isAuthenticated))}
return (
<Container component="main" maxWidth="xs">
<Box
sx={{
marginTop: 8,
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography component="h1" variant="h1">
Sign in
</Typography>
<Box component="form" onSubmit={(e) => onSubmit(e)} sx={{ mt: 1 }}>
<TextField
margin="normal"
helperText={formError.email}
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
onChange={(e) => onChange(e)}
value={formData.email}
error={formError.email ? true : false}
/>
<TextField
margin="normal"
helperText={formError.password}
error={formError.password ? true : false}
fullWidth
name="password"
label="Password"
value={formData.password}
type={showPassword ? "text" : "password"}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
color="primary"
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
}}
id="password"
autoComplete="current-password"
onChange={(e) => onChange(e)}
/>
<Box
sx={{
display: "flex",
mt: 1,
justifyContent: "flex-end",
}}
>
<Link component={routerLink} to="/Pass-Reset" variant="body2">
Forgot password?
</Link>
</Box>
<CButton props="login" />
<Divider
sx={{
my: 3,
}}
>
OR
</Divider>
<Button
fullWidth
variant="outlined"
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
my: 4,
p: 1,
}}
>
<Box
sx={{
display: "flex",
mx: 2,
alignItems: "center",
}}
>
<img
width="35"
height="35"
src="https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg"
alt="google icon"
/>
</Box>
<Box>
<Typography variant="body1" component="p">
Sign in with Google
</Typography>
</Box>
</Button>
<Box
sx={{
display: "flex",
justifyContent: "center",
}}
>
<Link component={routerLink} to="/Signup" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Box>
</Box>
</Box>
</Container>
);
};
function mapStateToProps(state) {
const isAuthenticated = state.auth.isAuthenticated;
return {isAuthenticated}
}
export default connect(mapStateToProps, { login })(Login);
Error it is showingenter image description here
here are the most common reason why this error occurs,
-
You are trying to render an object directly. Check the component that’s rendering the data and make sure that you’re not trying to render an object directly. If you are, you’ll need to convert the object to a string or some other type of data that React can render.
-
You are passing an object as a prop. Check the props that are being passed to the component and make sure that you’re not passing an object directly. If you are, you’ll need to convert the object to a string or some other type of data before passing it as a prop.
-
You are trying to render an array. React allows you to render an array of React elements, but not an array of objects. If you’re trying to render an array, make sure that each item in the array is a React element.
-
You are rendering a component that’s not returning anything. Make sure that the component you’re rendering is returning a valid React element. If the component is not returning anything, React will throw the "objects are not valid as a React child" error.
but neither i am rendering an array, nor an object. the line in my code where i am checking the state, if it is true, removing this peice of code and the erorors diss<appear but i need this function to redirect the user.
if (isAuthenticated) {
return redirect("/");
}else{
console.log(typeof(isAuthenticated))}
2
Answers
Here's what I updated:
It's working perfectly now
The only oddness or incorrect thing I see in the
Login
component is where you return a redirect response object from the render function.redirect
is a utility function meant to only be used in data router’sloader
andaction
functions. It returns aResponse
object, which is the object theLogin
component is trying to render.It’s basically returning the following to be rendered, which isn’t valid JSX:
See source code and
redirect
documentation for more details.If you want to effect a navigation action you should either import the
useNavigate
hook and issue an imperative redirect from theuseEffect
hook or a callbackor import and render the [
Navigate][3]
component to issue a declarative redirect.