简体   繁体   中英

Redux State is not updating when calling API using redux-promise

Currently I'm taking time to learn React and Redux and in general I'm new to coding. Unfortunately I got to a point where I'm stuck.

So I can send a message and when I call the api manually the messages will show up. Also the redux-logger shows the messages array with content. But it seems like that it will not save the messages to the state. Which means when I reload the page (as I have not implemented an auto reload yet). It will only show the input and button tag. For the messages it gets the information from the initialState which is empty.

action/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
  };
}

index.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')
);

reducers/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;
  }
}

Your reduced should look like below as you need to return the new state after update the old one.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM