0

我一直在调试为什么我的状态没有改变,并注意到这被记录在我的减速器中:

{ type: '@@redux/INITi.8.g.w.a.m' }

这是包含状态、动作类型、reducer、动作的商店:

/* initial state */
import axios from 'axios';

export var usersStartState = {
  accountNotVerified: null,
  isLoggedIn: false,
  error: true,
  userAvatar: 'uploads/avatar/placeholder.jpg'
};

/* action types */
export const actionTypes = {
  RESET_USER_ACCOUNT_IS_VERIFIED: 'RESET_USER_ACCOUNT_IS_VERIFIED',
  USER_ACCOUNT_IS_VERIFIED: 'USER_ACCOUNT_IS_VERIFIED',
  USER_ACCOUNT_NOT_VERIFIED: 'USER_ACCOUNT_NOT_VERIFIED',
  IS_LOGGED_IN: 'IS_LOGGED_IN',
  IS_LOGGED_OUT: 'IS_LOGGED_OUT',
  LOAD_USER_AVATAR: 'LOAD_USER_AVATAR',
  ERROR_LOADING: 'ERROR_LOADING' // LOAD_MULTER_IMAGE: "LOAD_MULTER_IMAGE"
};

/* reducer(s) */
export default function users(state = usersStartState, action) {
  console.log('In users reducer! ', action);
  switch (action.type) {
    case actionTypes.RESET_USER_ACCOUNT_IS_VERIFIED:
      return Object.assign({}, state, { accountNotVerified: null });

    case actionTypes.USER_ACCOUNT_IS_VERIFIED:
      return Object.assign({}, state, { accountNotVerified: false });

    case actionTypes.USER_ACCOUNT_NOT_VERIFIED:
      return Object.assign({}, state, { accountNotVerified: true });

    case actionTypes.IS_LOGGED_IN:
      return Object.assign({}, state, { isLoggedIn: true });

    case actionTypes.IS_LOGGED_OUT:
      return Object.assign({}, state, { isLoggedIn: false });

    case actionTypes.LOAD_USER_AVATAR:
      return { ...state, userAvatar: action.data };

    case actionTypes.ERROR_LOADING:
      return Object.assign({}, state, { error: true });

    default:
      return state;
  }
}

/* actions */
export const resetUserAcoountVerified = () => {
  return { type: actionTypes.RESET_USER_ACCOUNT_IS_VERIFIED };
};

export const userHasBeenVerified = () => {
  return { type: actionTypes.USER_ACCOUNT_IS_VERIFIED };
};

export const userHasNotBeenVerified = () => {
  return { type: actionTypes.USER_ACCOUNT_NOT_VERIFIED };
};

export const logInUser = () => {
  return { type: actionTypes.IS_LOGGED_IN };
};

export const logOutUser = () => {
  axios
    .get('/users/logout')
    .then(response => {
      if (response.status === 200) {
        console.log('You have been logged out!');
      }
    })
    .catch(function(error) {
      if (error.response.status === 500) {
        console.log('An error has occured');
      }
    });
  return { type: actionTypes.IS_LOGGED_OUT };
};

export const loadAvatar = data => {
  console.log('in load avatar ', data);

  return { type: actionTypes.LOAD_USER_AVATAR, data: data };
};

export const errorLoading = () => {
  return { type: actionTypes.ERROR_LOADING };
};

这是我的组件:

import { useState } from 'react';

import { Card, Icon, Image, Segment, Form } from 'semantic-ui-react';

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { loadAvatar } from '../../store/reducers/users/index';

import axios from 'axios';

function ImageUploader({ userAvatar }) {
  var [localUserAvatar, setLocalUserAvatar] = useState(userAvatar);
  function fileUploader(e) {
    e.persist();

    var imageFormObj = new FormData();

    imageFormObj.append('imageName', 'multer-image-' + Date.now());
    imageFormObj.append('imageData', e.target.files[0]);
    loadAvatar('foo');

    axios({
      method: 'post',
      url: `/users/uploadmulter`,
      data: imageFormObj,
      config: { headers: { 'Content-Type': 'multipart/form-data' } }
    })
      .then(data => {
        if (data.status === 200) {
          console.log('data ', data);
          console.log('path typeof ', typeof data.data.path);
          loadAvatar('foo');

          setLocalUserAvatar('../../' + data.data.path);
        }
      })
      .catch(err => {
        alert('Error while uploading image using multer');
      });
  }

这里是 console.log('userAvatar in imageUploader ', userAvatar); console.log('Date.now() 第 44 行 in imageUploader ', Date.now()); console.log('localUserAvatar in imageUploader ', localUserAvatar); console.log('Date.now() 第 46 行 in imageUploader ', Date.now());

  console.log("loadAvatar('barbar') ", loadAvatar('barbar'));

  return (
    <>
      <Segment>
        <Card fluid>
          <Image src={localUserAvatar} alt="upload-image" />
          <Segment>
            <Form encType="multipart/form-data">
              <Form.Field>
                <input
                  placeholder="Name of image"
                  className="process__upload-btn"
                  type="file"
                  content="Edit your Avatar!"
                  onChange={e => fileUploader(e)}
                />
              </Form.Field>
            </Form>
          </Segment>
          <Card.Content>
            <Card.Header>Charly</Card.Header>
            <Card.Meta>
              <span className="date">Joined in 2015</span>
            </Card.Meta>
            <Card.Description>Charly</Card.Description>
          </Card.Content>
          <Card.Content extra>
            <a>
              <Icon name="user" />
              22 Friends
            </a>
          </Card.Content>
        </Card>
      </Segment>
    </>
  );
}

function mapStateToProps(state) {
  const { users } = state;
  const { userAvatar } = users;

  return { userAvatar };
}

const mapDispatchToProps = dispatch => bindActionCreators({ loadAvatar }, dispatch);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(ImageUploader);

在此处输入图像描述

从日志中您可以看到loadAvatar调度程序,在组件和存储中被触发......

但是商店里的状态永远不会改变......

其他状态也确实会正确更改...例如,我有一个 Modal 并且可以很好地更新。

任何帮助将不胜感激{ type: '@@redux/INITi.8.g.w.a.m' },因为我的状态是什么以及为什么没有更新?

4

1 回答 1

0

Redux 将该操作作为内部初始化步骤分派

  // When a store is created, an "INIT" action is dispatched so that every
  // reducer returns their initial state. This effectively populates
  // the initial state tree.
  dispatch({ type: ActionTypes.INIT })

这特别是为了让您的减速器将看到动作,识别动作类型,并返回它们的默认状态,从而定义初始的整体应用程序状态内容。

于 2020-05-25T14:17:57.860 回答