对象作为React子对象无效(找到:[object Response])使用react redux时

14ifxucb  于 2023-05-07  发布在  React
关注(0)|答案(2)|浏览(127)

我正在使用Django rest framework(Djoser)构建一个react应用程序以进行认证。现在我使用react redx来管理身份验证。bt在使用connect方法传递stattoprops时不知何故得到此错误。而不是错误的确切位置。
以下是我的档案:减速器Atyh文件:

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
    }}

操作身份验证文件:

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;

登录屏幕:

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);

显示enter image description here时出错

以下是发生此错误的最常见原因,

  • 您正尝试直接渲染对象。检查渲染数据的组件,并确保您没有尝试直接渲染对象。如果是,你需要将对象转换为字符串或其他类型的数据,React可以渲染。
  • 你正在传递一个对象作为 prop 。检查传递给组件的props,确保没有直接传递对象。如果是,则需要在将对象作为prop传递之前将其转换为字符串或其他类型的数据。
  • 您正在尝试呈现数组。React允许你渲染一个React元素数组,但不是一个对象数组。如果你试图呈现一个数组,请确保数组中的每个元素都是React元素。
  • 你正在呈现一个不返回任何东西的组件。确保你渲染的组件返回一个有效的React元素。如果组件没有返回任何内容,React将抛出“objects are not valid as a React child”错误。

但我既不是在渲染数组,也不是对象。在我的代码行,我检查状态,如果它是真的,删除这段代码和错误diss〈出现,但我需要这个功能来重定向用户。

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

  console.log(typeof(isAuthenticated))}
dffbzjpn

dffbzjpn1#

我在Login组件中看到的唯一奇怪或不正确的地方是从render函数返回重定向响应对象。

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

redirect是一个实用程序函数,仅用于数据路由器的loaderaction函数。它返回一个Response对象,该对象是Login组件试图呈现的对象。
它基本上返回以下要呈现的内容,这不是有效的JSX:

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

有关更多详细信息,请参阅源代码和redirect文档。
如果要实现导航操作,则应导入useNavigate钩子并从useEffect钩子发出命令式重定向或回调

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 (
    ...
  );
};

或导入并呈现[ Navigate][3]组件以发出声明性重定向。

import { Link as RouterLink, Navigate } from "react-router-dom";
...

const Login = ({ login, isAuthenticated }) => {
  ...

  if (isAuthenticated) {
    return <Navigate to="/" replace />;
  }

  return (
    ...
  );
};
lndjwyie

lndjwyie2#

以下是我更新的内容:

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

  console.log(typeof(isAuthenticated))}

现在运行得很完美

相关问题