首页 > 解决方案 > 使用 redux-promise 调用 API 时 Redux 状态未更新

问题描述

目前我正在花时间学习 React 和 Redux,总的来说我是编码新手。不幸的是,我到了卡住的地步。

所以我可以发送一条消息,当我手动调用 api 时,消息会显示出来。redux-logger 还显示带有内容的消息数组。但似乎它不会将消息保存到状态。这意味着当我重新加载页面时(因为我还没有实现自动重新加载)。它只会显示输入和按钮标签。对于消息,它从为空的 initialState 获取信息。

动作/index.js

const BASE_URL = '********************';

const FETCH_MESSAGES = 'FETCH_MESSAGES';
const SEND_MESSAGE = 'SEND_MESSAGE';

export function fetchMessages(channel) {
  const url = `${BASE_URL}${channel}/messages`;
  const promise = fetch(url).then(reason => reason.json());

  return {
    type: FETCH_MESSAGES,
    payload: promise
  };
}

export function createMessage(channel, author, content) {
  const body = { channel, author, content };
  const url = `${BASE_URL}${channel}/messages`;
  const promise = fetch(url, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  }).then(reason => reason.json());

  return {
    type: SEND_MESSAGE,
    payload: promise
  };
}

索引.jsx

// external modules
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import logger from 'redux-logger';
import reduxPromise from 'redux-promise';

// internal modules
import App from './components/app';
import '../assets/stylesheets/application.scss';

// Reducer
import messagesReducer from './reducers/messages_reducer';
import selectedChannelReducer from './reducers/selected_channel_reducer';

const identityReducer = (state = null) => state;

const initialState = {
  messages: [],
  channels: ['general', 'react', 'berlin'],
  currentUser: prompt("What is your username?") || `anonymous${Math.floor(10 + (Math.random() * 90))}`,
  selectedChannel: 'react'
};

// State and reducers
const reducers = combineReducers({
  messages: messagesReducer,
  channels: identityReducer,
  currentUser: identityReducer,
  selectedChannel: selectedChannelReducer
});

const middleWares = applyMiddleware(logger, reduxPromise);

// render an instance of the component in the DOM
ReactDOM.render(
  <Provider store={createStore(reducers, initialState, middleWares)}>
    <App />
  </Provider>,
  document.getElementById('root')
);

减速器/messages_reducer.js

import { FETCH_MESSAGES, SEND_MESSAGE } from '../actions';

export default function(state = null, action) {
  switch (action.type) {
    case FETCH_MESSAGES: {
      return action.payload.messages;
    }
    case SEND_MESSAGE: {
      const copiedState = state.slice(0);
      copiedState.push(action.payload);
      return copiedState;
    }
    default:
      return state;
  }
}

标签: javascriptreactjsreduxreact-redux

解决方案


您的 reduce 应该如下所示,因为您需要在更新旧状态后返回新状态。

import { FETCH_MESSAGES, SEND_MESSAGE } from '../actions';

export default function(state = null, action) {
  switch (action.type) {
    case FETCH_MESSAGES: {
      const newState = {...state};
      newState.messages = action.payload.messages;
      return newState;
    }
    case SEND_MESSAGE: {
      const newState = {...state};
      const copiedState = state.slice(0);
      newState.copiedState = [];
      newState.copiedState.push(action.payload);
      return newState;
    }
    default:
      return state;
  }
}

推荐阅读