【问题标题】:Redux does not work now that I am using hooks and functional component?既然我使用了钩子和功能组件,Redux 就不能工作了?
【发布时间】:2021-04-01 15:50:40
【问题描述】:

我一直在学习更多关于用于创建功能组件的 reactjs 钩子,因为我在该领域缺乏很多知识。我正在使用 redux,但我似乎无法让我的操作在我的功能组件中正常工作。由于我在其中设置了 console.log,我的操作似乎永远不会被调用,因此数据数组和列表始终为空,但不会引发任何错误。代码如下。

这是配置文件组件:

import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Redirect, Link as RouterLink } from 'react-router-dom';
import { getUserListings } from '../../actions/listings';
import { getUserInfo } from '../../actions/users';
//material ui
import {
  Container,
  Typography,
  withStyles,
  Grid,
  Paper,
  Button,
  Link,
} from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import listings from '../../reducers/listings';

//antd
import { List, Avatar, Button as antButton, Skeleton, Row, Col } from 'antd';
import 'antd/dist/antd.css';

const useStyles = makeStyles({
  imgBox: {
    backgroundColor: 'white',
    height: '300px',
    marginTop: '30px',
    width: '400px',
    marginRight: '10px',
  },
  userBox: {
    backgroundColor: 'white',
    height: '300px',
    width: '700px',
    marginTop: '30px',
  },
  dashBox: {
    backgroundColor: 'white',
    height: '650px',
    width: '1110px',
    marginTop: '30px',
  },
});

const Profile = () => {
  const [loading, setLoading] = useState(false);
  const isAuth = useSelector((state) => state.users.isAuth); //using hook to pull state out from store
  const classes = useStyles();

  useEffect(() => {
    setLoading(true);
    getUserInfo();
    getUserListings();
  }, []);

  const listings = useSelector((state) => state.listings.listings);
  const user = useSelector((state) => state.users.user);

  if (!isAuth) {
    return <Redirect to={'/login'}></Redirect>;
  }

  return (
    <>
      <Row justify='center'>
        <Col>
          <Container className={classes.imgBox}></Container>
        </Col>
        <Col>
          <Container className={classes.userBox}></Container>
        </Col>
      </Row>

      <Row justify='center'>
        <Col>
          <Container className={classes.dashBox}>
            {listings.map((listing) => (
              <h3>{listing.title}</h3>
            ))}
          </Container>
        </Col>
      </Row>
    </>
  );
};

export default Profile;

以下是操作:

export const getUserListings = () => (dispatch) => {
  axiosInstance.get('/listings/userlistings').then((res) => {
    console.log('made it'); //never makes it here
    dispatch({
      type: GET_LISTINGS,
      payload: res.data,
    });
  });
};

export const getUserInfo = () => (dispatch) => {
  axiosInstance
    .get('/auth/getuserinfo')
    .then((res) => {
      dispatch({
        type: GET_USER_INFO,
        payload: res.data,
      });
    })
    .catch((err) => {
      console.log(err); //need to dispatch an error message here
    });
};

这里是减速器:

import {
  GET_LISTINGS,
  GET_LISTING,
  CREATE_LISTING,
  CLEAR_LISTINGS,
} from '../actions/types';

const initialState = {
  listings: [],
  isLoading: true, //ignore this for now never use it
};

export default function (state = initialState, action) {
  switch (action.type) {
    case GET_LISTINGS:
      return {
        ...state,
        listings: action.payload,
        isLoading: false,
      };
    case GET_LISTING:
      return {
        ...state,
        listings: action.payload,
        isLoading: false,
      };
    case CREATE_LISTING:
      return {
        ...state,
        listings: [...state.listings, action.payload],
      };
    case CLEAR_LISTINGS:
      return {
        ...state,
        listings: [],
      };
    default:
      return state;
  }
}

import {
  LOGIN_SUCCESS,
  REGISTER_SUCCESS,
  REGISTER_FAIL,
  LOGIN_FAIL,
  LOGOUT_SUCCESS,
  GET_USER_INFO,
} from '../actions/types';

const initialState = {
  isAuth: localStorage.getItem('isAuth'),
  user: {},
};

export default function (state = initialState, action) {
  switch (action.type) {
    case LOGIN_SUCCESS:
    case REGISTER_SUCCESS:
      const access = action.payload.accessToken;
      const refresh = action.payload.refreshToken;
      localStorage.setItem('accessToken', access);
      localStorage.setItem('refreshToken', refresh);
      localStorage.setItem('isAuth', true);
      return {
        ...state,
        isAuth: true,
      };
    case GET_USER_INFO:
      return {
        ...state,
        user: action.payload,
      };
    case LOGIN_FAIL:
    case LOGOUT_SUCCESS:
    case REGISTER_FAIL:
      localStorage.removeItem('accessToken');
      localStorage.removeItem('refreshToken');
      localStorage.removeItem('isAuth');
      return {
        ...state,
        user: {},
        isAuth: false,
      };
    default:
      return state;
  }
}

我没有收到任何错误,如果我称操作错误或者我的状态都搞砸了。对 reactjs 相当陌生!

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    您需要调度您的操作以使其与 redux 无缝协作,您可以使用 useDispatch。到目前为止,您只是在调用您的操作,它们只返回嵌套函数。您需要更新您的代码,例如

    const dispatch = useDispatch();
    
      useEffect(() => {
        setLoading(true);
        dispatch(getUserInfo());
        dispatch(getUserListings());
      }, []);
    

    【讨论】:

      【解决方案2】:

      当你这样做时

          getUserInfo();
          getUserListings();
      

      你所做的只是创建函数。

      你应该做的是改变你的行为,比如:

      export const getUserInfo = (dispatch) => {
        axiosInstance
          .get('/auth/getuserinfo')
          .then((res) => {
            dispatch({
              type: GET_USER_INFO,
              payload: res.data,
            });
          })
          .catch((err) => {
            console.log(err); //need to dispatch an error message here
          });
      };
      
      

      然后在你的组件中

        const dispatch = useDispatch()
        useEffect(() => {
          setLoading(true);
          getUserInfo(dispatch);
          getUserListings(dispatch);
        }, []);
      

      请注意,您进行 api 调用的方式应该可行,但通常更喜欢使用一些专用中间件(如 redux-thunk)将异步调用分开

      【讨论】:

      • 啊,这行得通,谢谢!你对我的 api 调用到底意味着什么?
      猜你喜欢
      • 2019-12-29
      • 2018-08-09
      • 2019-12-22
      • 2020-01-28
      • 2020-02-13
      • 1970-01-01
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多