Redux: мое состояние получает '@@redux/INITi.8.gwam' Состояние Redux не обновляется

Я отлаживал, почему мое состояние не меняется, и заметил, что это регистрируется в моем редукторе:

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

Это магазин, который включает в себя состояние, типы действий, редуктор, действия:

/* 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 в imageUploader ', Date.now()); console.log('localUserAvatar в imageUploader ', localUserAvatar); console.log('Date.now() строка 46 в 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 диспетчер запускается в компоненте и в магазине...

Но состояние в магазине никогда не меняется....

Также другие состояния меняются правильно... Например, у меня есть модальное окно, и оно хорошо обновляется.

Любая помощь будет оценена как то, что { type: '@@redux/INITi.8.g.w.a.m' } и почему мое состояние не обновляется?

1 ответ

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

Это специально сделано для того, чтобы ваши редукторы видели действие, не распознавали тип действия и возвращали свое состояние по умолчанию, тем самым определяя исходное общее содержимое состояния приложения.

Другие вопросы по тегам