Обновление состояния redux в разбитом на страницы laravel api

#javascript #laravel #redux #react-redux #state

#javascript #laravel #redux #реагировать-redux #состояние

Вопрос:

Добрый день всем. Я столкнулся с этой проблемой в проекте, над которым я работаю. У меня есть laravel API, который возвращает разбитые на страницы данные. Структура выглядит следующим образом

 {
"current_page": 4,
"data": [
{
"id": 8,
"name": "Gage Gulgowski",
"anonymous": true,
"message": "Tempora amet id porro saepe totam consequatur. Qui porro dolorum aspernatur rerum inventore ipsum et. Soluta
ducimus quia nostrum ea.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 4,
"info": "illum"
},
{
"id": 7,
"name": "Jessy Rosenbaum PhD",
"anonymous": true,
"message": "Aspernatur optio sint voluptatum iure. Nesciunt aliquam magnam ducimus aperiam error laborum molestiae odit.
Facere tempore aliquid ut occaecati quo fugiat.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 8,
"info": "cupiditate"
},
{
"id": 6,
"name": "Rhianna Jaskolski",
"anonymous": false,
"message": "Assumenda repellat quia totam ab similique aut distinctio. Nesciunt et et id debitis quas. Atque neque quia
ut aut commodi ut.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 4,
"info": "perferendis"
},
{
"id": 5,
"name": "Dr. Raquel Stamm IV",
"anonymous": false,
"message": "Voluptas voluptatem impedit illum quia est accusantium porro. Sunt quia dolorem quia animi quo corporis.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 0,
"info": "temporibus"
},
{
"id": 4,
"name": "Donavon Predovic",
"anonymous": true,
"message": "Deleniti porro modi quae quam accusantium. Vero eligendi optio nesciunt sit accusamus dolores tenetur
labore. Explicabo qui voluptatem culpa quis. Et quia est reprehenderit qui fugit et.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 6,
"info": "non"
},
{
"id": 3,
"name": "Mr. Osbaldo Wilkinson",
"anonymous": false,
"message": "Vel consectetur dicta magni est quia laboriosam voluptatem ab. Voluptas vel officia saepe. Facere molestiae
quis cum voluptate quia et voluptatem. Fuga quia commodi qui eius et.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 7,
"info": "odio"
},
{
"id": 2,
"name": "Lew Nitzsche",
"anonymous": true,
"message": "Nobis sunt eaque soluta voluptatibus iure culpa. Minus ut consequatur blanditiis commodi.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T20:56:49.000000Z",
"votes": 0,
"info": "eos"
},
{
"id": 1,
"name": "Adalberto Jones",
"anonymous": true,
"message": "Qui nisi aperiam culpa et. Earum et veniam aut et et neque aut officiis. Debitis eos sequi quasi et. Qui
iusto saepe qui necessitatibus ut.",
"created_at": "2020-11-29T20:56:49.000000Z",
"updated_at": "2020-11-29T22:17:25.000000Z",
"votes": 8,
"info": "ex"
}
],
"first_page_url": "http://tomilola.herokuapp.com/api/messages?page=1",
"from": 31,
"last_page": 4,
"last_page_url": "http://tomilola.herokuapp.com/api/messages?page=4",
"links": [
{
"url": "http://tomilola.herokuapp.com/api/messages?page=3",
"label": "amp;laquo; Previous",
"active": false
},
{
"url": "http://tomilola.herokuapp.com/api/messages?page=1",
"label": 1,
"active": false
},
{
"url": "http://tomilola.herokuapp.com/api/messages?page=2",
"label": 2,
"active": false
},
{
"url": "http://tomilola.herokuapp.com/api/messages?page=3",
"label": 3,
"active": false
},
{
"url": "http://tomilola.herokuapp.com/api/messages?page=4",
"label": 4,
"active": true
},
{
"url": null,
"label": "Next amp;raquo;",
"active": false
}
],
"next_page_url": null,
"path": "http://tomilola.herokuapp.com/api/messages",
"per_page": 10,
"prev_page_url": "http://tomilola.herokuapp.com/api/messages?page=3",
"to": 38,
"total": 38
}
 

Теперь, в моем react, я настроил свое сокращение следующим образом.

  1. ActionTypes.js
 export const MESSAGES_LOADING = 'MESSAGES_LOADING';
export const ADD_MESSAGES = 'ADD_MESSAGES';
export const MESSAGES_FAILED = 'MESSAGES_FAILED';

//Post message
export const ADD_MESSAGE = 'ADD_MESSAGE';
export const MESSAGE_FAILED = 'MESSAGE_FAILED';
 
  1. ActionCreator.js
 import * as ActionTypes from './ActionTypes';
import { baseUrl } from '../shared/baseUrl';




export const fetchMessages = (page) => (dispatch) => {
    
    dispatch(messagesLoading());
    let url; 
    if(page == ""){
     url = 'https://tomilola.herokuapp.com/api/messages';
    }else{
     url = 'https://tomilola.herokuapp.com/api/messages?page=' page;
    }
    
    return fetch(url)
    .then(response => {
        if (response.ok) {
            return response;
        } else {
            
            var error = new Error('Error '   response.status   ': '   response.statusText);
            error.response = response;
            throw error;
        }
        },
        error => {
            var errmess = new Error(error.message);
            throw errmess;
        })
    .then(response => response.json())
    .then(messages => dispatch(addMessages(messages)))
    .catch(error => dispatch(messagesFailed(error.message)));
}

export const messagesLoading = () => ({
    type: ActionTypes.MESSAGES_LOADING
});

export const messagesFailed = (errmess) => ({
    type: ActionTypes.MESSAGES_FAILED,
    payload: errmess
});

export const addMessages = (messages) => ({
    type: ActionTypes.ADD_MESSAGES,
    payload: messages
});


//For posting message
export const addMessage = (message) => ({
    type: ActionTypes.ADD_MESSAGE,
    payload: message
});


export const postMessage = (name, message, anonymous,info) => (dispatch) => {

    const newMessage = {
        name: name,
        message: message,
        anonymous: anonymous,
        info: info
    }
    //console.log('Message is this', newMessage);
  

    return fetch(baseUrl   'messages', {
        method: 'POST',
        body: JSON.stringify(newMessage),
        headers: {
            'Content-Type': 'application/json',
        },
        credentials: 'same-origin'
    })
    .then(response => {
        if (response.ok) {
            return response;
        }
        else {
            var error = new Error('Error '   response.status   ': '   response.statusText);
            error.response = response;
            throw error;
        }
    },
    error => {
        var errmess = new Error(error.message);
        throw errmess;
    })
    .then(response => response.json())
    .then(response => dispatch(addMessage(response)))
    .catch(error => { console.log('Post messages ', error.message);
        alert('Your message could not be postednError: '  error.message); })
    alert('message posted');
    
}

 
  1. ConfigureStore.js
 import { createStore, combineReducers, applyMiddleware } from 'redux';
import { Messages } from './messages';
import thunk from 'redux-thunk';
import logger from 'redux-logger';


export const ConfigureStore = () => {
    const store = createStore(
        combineReducers({
            messages: Messages,
        }),
        applyMiddleware(thunk, logger)
    );

    return store;
}
 
  1. messages.js
 import * as ActionTypes from './ActionTypes';

export const Messages = (state  = { isLoading: true,
                                        errMess: null,
                                        messages:[]}, action) => {
    switch (action.type) {
        case ActionTypes.ADD_MESSAGES:
        return {...state, isLoading: false, errMess: null, messages: action.payload};

        case ActionTypes.MESSAGES_LOADING:
            return {...state, isLoading: true, errMess: null, messages: []}

        case ActionTypes.MESSAGES_FAILED:
            return {...state, isLoading: false, errMess: action.payload, messages : []};

        case ActionTypes.ADD_MESSAGE: //For actually posting the message
            var message = action.payload;
            
            return {...state, messages: state.messages};    

        default:
          return state;
      }
};
 

Данные извлекаются правильно, и разбивка на страницы работает хорошо. Проблема в том, как мне обновить свое состояние после публикации в базе данных. Обратите внимание, что всякий раз, когда я отправляю сообщение в api, данные сохраняются в базе данных, но состояние не обновляется, пока я не обновлю страницу.
Кроме того, если бы он не был разбит на страницы, я бы использовал return {...state, messages: state.messages.concat(message)}; в своем messages.js редуктор.

  1. В моем основном компоненте представления мои функции выглядят следующим образом
 const mapStateToProps = state => {
    state.messages.messages amp;amp; console.log(state.messages.messages);
    return {
      messages: state.messages,
      likes: state.likes,
    }
}

const mapDispatchToProps = (dispatch) => ({
    postMessage: (name, message, anonymous) => dispatch(postMessage(name, message, anonymous)),
    fetchMessages: (page) => dispatch(fetchMessages(page)),
    postLike: (messageId) => dispatch(postLike(messageId))
  });
 

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

Ответ №1:

Когда вы разбиваете на страницы (повторно нажимая на api) полученный вами ответ, не можете ли вы использовать эти данные для отправки типа действия вашего redux? Как вы вызываете действие разбиения на страницы?

Комментарии:

1. У меня нет проблем с нумерацией страниц. Я отправляю функцию ‘fetchMessages’ с дополнительным параметром страницы. Вы имеете в виду, что я должен выполнить повторную выборку после успешной отправки post?

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