在Redux Reducer达到状态之前格式化日期

Le *_*Moi 5 javascript reactjs redux

如何从标准JS日期对象格式化日期,该日期对象来自服务器,并通过REST API通过Redux提供给React,其初始输出为:

"2016-05-16T13:07:00.000Z"
Run Code Online (Sandbox Code Playgroud)

成不同的格式?所以它被列为DD MM YYYY

我可以通过操作请求结果或有效负载在Reducer of Action中执行此操作:

import { FETCH_BOOKS, FETCH_BOOK } from '../actions';

const INITIAL_STATE = { books: [], book: null };

export default function(state = INITIAL_STATE, action) {
    switch(action.type) {
        case FETCH_BOOK:
            return { ...state, book: action.payload.data };
        case FETCH_BOOKS:
            return { ...state, books: action.payload.data };
    }
    return state;
}
Run Code Online (Sandbox Code Playgroud)

行动:

export function fetchBooks() {
    const request = axios.get('/api/books');

    return {
        type: FETCH_BOOKS,
        payload: request
    }
}
Run Code Online (Sandbox Code Playgroud)

fetchBooks()componentWillMount()在Books React组件的方法中调用:

componentWillMount() {
    this.props.fetchBooks();
}
Run Code Online (Sandbox Code Playgroud)

api返回以下结构化JSON:

[{"_id":0,"date":"2016-05-16T13:07:00.000Z","title":"Eloquent JavaScript","description":"Learn JavaScript"}]
Run Code Online (Sandbox Code Playgroud)

更新

非常感谢Nicole和nrabinowitz - 我已经在动作创建者中实现了以下更改

function transformDateFormat(json) {
    const book = {
        ...json,
        id: json.data._id,
        // date: new Date(moment(json.data.date).format('yyyy-MM-dd'))
        date: new Date(json.data.date)
    }
    console.log(book);
    return book;
}

export function fetchBook(id) {
    const request = axios.get(`/api/books/${id}`)
        .then(transformDateFormat);

    return {
        type: FETCH_BOOK,
        payload: request 
    }
};
Run Code Online (Sandbox Code Playgroud)

我登录在变换日期函数该书对象,它是增加iddate对象的根,但JSON的结构实际上必须book.data.idbook.data.date.我不确定如何在transformDate函数中创建正确的结构以返回到动作创建者.

这是转换日期函数控制台日志中的book对象:

Object {data: Object, status: 200, statusText: "OK", headers: Object, config: Object…}
config: Object
data: Object
    __v:0
    _id: "5749f1e0c373602b0e000001"
    date: "2016-05-28T00:00:00.000Z"
    name:"Eloquent JavaScript"
    __proto__:Object
date: Sat May 28 2016 01:00:00 GMT+0100 (BST)
headers: Object
id: "5749f1e0c373602b0e000001"
request: XMLHttpRequest
status: 200
statusText: "OK"
__proto__: Object
Run Code Online (Sandbox Code Playgroud)

我的函数需要将id和date放在数据对象中.(日期只是标准日期格式,因为我执行的时刻(date: new Date(moment(json.data.date).format('yyyy-MM-dd'))返回Invalid date)有问题.

再次感谢您的帮助 - 真的很感激.

Nic*_*ole 8

当数据到达前端时,即在您的AJAX请求中,我会立即进行此转换.这样,您的前端应用程序仅在您希望对数据进行整形时才对数据起作用,并且您的请求处理程序封装和隐藏数据结构,因为它们是从服务器提供的,并以期望的形状将数据传递给前端应用程序.

(在域驱动设计中,这称为"反腐层").

关于技术方案:

目前,您的事件有效负载包含对数据的承诺.您没有告诉我们您调用的位置fetchBooks(),即执行承诺的位置.这就是您需要进行数据转换的地方.(但就个人而言,我宁愿将数据转换保留在fetchBooks函数内部.)

此外,您需要将数据发送到redux商店.为了能够异步减少事件,你需要类似的东西redux-thunk.

解决方案可能看起来像这样(道歉,我在使用promises方面不是很有经验,所以我会在这里使用回调,但也许你可以以某种方式将其转换为承诺):

export function fetchBooks(callback) {
    const request = axios.get('/api/books')
                    .then(function (response) {
                       callback(transformData(response));
                    });
}
Run Code Online (Sandbox Code Playgroud)

transformData 应该做从后端格式到前端格式的日期转换.

在其他地方你可能会触发一个动作,以便获取书籍(我们暂时调用它loadBooks).这就是你需要进行异步调度的地方:

function loadBooks() {
    return (dispatch, getState) => {

        fetchBooks(response => {
            dispatch(receiveBooks(response));
        });
    };
}

function receiveBooks(data) {
    return {
        type: FETCH_BOOKS,
        payload: data
    };
}
Run Code Online (Sandbox Code Playgroud)

这样,只有在从AJAX调用实际返回后,才会将数据分派到redux存储.

要使用redux-thunk,您需要将其中间件注入您的商店,如下所示:

import thunkMiddleware from "redux-thunk";
import { createStore, applyMiddleware } from "redux";

const createStoreWithMiddleware = applyMiddleware(
    thunkMiddleware
)(createStore);
Run Code Online (Sandbox Code Playgroud)

然后将reducers函数传递给此商店.

请继续询问您是否还有其他问题.