skip to Main Content

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


  1. Chosen as BEST ANSWER

    Here's what I updated:

     if (isAuthenticated) {
        console.log('Its working');
        navigate("/");
      }else{
    
      console.log(typeof(isAuthenticated))}

    It's working perfectly now


  2. The only oddness or incorrect thing I see in the Login component is where you return a redirect response object from the render function.

    if (isAuthenticated) { 
      return redirect("/");
    }
    

    redirect is a utility function meant to only be used in data router’s loader and action functions. It returns a Response object, which is the object the Login component is trying to render.

    It’s basically returning the following to be rendered, which isn’t valid JSX:

    new Response("", {
      status: 302,
      headers: {
        Location: "/",
      },
    });
    

    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 the useEffect hook or a callback

    import { Link as RouterLink, useNavigate } from "react-router-dom";
    ...
    
    const Login = ({ login, isAuthenticated }) => {
      const navigate = useNavigate();
    
      ...
    
      useEffect(() => {
        if (isAuthenticated) {
          return navigate("/", { replace: true });
        }
      }, [isAuthenticated, navigate]);
    
      ...
    
      if (isAuthenticated) {
        return null;
      }
    
      return (
        ...
      );
    };
    

    or import and render the [Navigate][3] component to issue a declarative redirect.

    import { Link as RouterLink, Navigate } from "react-router-dom";
    ...
    
    const Login = ({ login, isAuthenticated }) => {
      ...
    
      if (isAuthenticated) {
        return <Navigate to="/" replace />;
      }
    
      return (
        ...
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search