4

我试图理解 Redux 并遇到了一些困难。

我理解 combineReducer 的概念,即....

var reducer = combineReducers({
    user: userReducer,
    products: productsReducer
})

但是,如果我有数千种产品,只能在产品页面上找到。我不明白为什么我需要在根目录下加载它们;对我来说,这会减慢应用程序的初始启动速度,因为除非用户转到产品页面,否则不需要这些东西。

这就是redux的方式吗?

4

3 回答 3

5

在 Redux 应用程序中,您总是在一开始就构建您的整个状态。使用 Redux,你有一个 store 和一个 state——一切都应该从一个 state 向下渗透到你的组件上的 props。但是,这并不意味着您实际上需要在启动时将所有数据加载到状态中,只是结构需要在那里。这就是为什么你应该为每个 reducer 设置一个初始状态对象。

假设您有数千条从数据库加载的产品记录。在您的产品减速器中,您可以执行以下操作:

const initialState = {
    data: []
};

//use ES6 default parameters
function productsReducer (state = initialState, action) {
    switch (action.type) {
    case 'GET_PRODUCTS':
        //return data from action
        return {
            data: action.result
        };
    default: 
        return state;
    }
}

这意味着当您启动您的应用程序时,如果您使用您在帖子中声明的完整 reducer,您的应用程序状态将如下所示:

{
    user: {},
    products: {
        data: []
    }
}

products.data将是一个空数组,直到您触发实际需要您加载产品数据的操作(即您转到应用程序中的产品页面或其他内容)。确实,如果您随后转到应用程序的其他位置,产品数据将保留在您的状态中,但这是一件好事 - 下次您呈现产品页面时,您将已经拥有可供您使用的数据,而无需创建数据库抬头。

于 2015-12-07T15:15:25.957 回答
0

在我们的应用程序中,我们为产品制作了一个 API,每页限制为 15 个。所以我们的减速器是这样的。

collection: {
  "total": 0,
  "per_page": 0,
  "current_page": 0,
  "last_page": 0,
  "from": 0,
  "to": 0,
  data: []
},

isFetching: false,
isFetchingError: false

在第一次加载时,我们获取了有限数量的产品,然后我们对其进行了分页.. 在 redux 中使用选择器https://github.com/rackt/reselect

加载成千上万的数据会使您的应用程序变得非常缓慢。

const paginated = (state = initialState, action) => {
 switch (action.type) {
case FETCH_PAGINATED_PRODUCTS:
  return {
    ...state,
    isFetching: true,
    isFetchingError: false
  };

case FETCH_PAGINATED_PRODUCTS_SUCCESS:
  return {
    ...state,
    collection: action.payload,
    isFetching: false
  };

case FETCH_PAGINATED_PRODUCTS_ERROR:
  return {
    ...state,
    isFetching: false,
    isFetchingError: true
  };

default:
 return state

我们用于axios请求: https ://github.com/mzabriskie/axios

于 2015-12-07T15:31:42.613 回答
0

下面是我们如何在 redux-async 中实现 axios

 export function getAll(page = 1) {
  return (dispatch, getState) => {
    const state = getState();
    const { filters } = state.products.paginated;

    if ( state.products.paginated.isFetching ) {
      return;
    }

    dispatch({ type: FETCH_PAGINATED_PRODUCTS });

    return axios
      .get(`products?page=${page}&limit=16&filters=${JSON.stringify(filters)}`)
      .then((res) => dispatch({
        type: FETCH_PAGINATED_PRODUCTS_SUCCESS,
        payload: res.data
      }))
      .catch((res) => dispatch({
        type: FETCH_PAGINATED_PRODUCTS_ERROR,
        /*payload: res.data.error,*/
        error: true
      }));
  }
}

export function get(id) {
  return (dispatch, getState) => {
    const state = getState();

    if ( state.products.resource.isFetching ) {
      return;
    }

    dispatch({ type: FETCH_PRODUCT });

    return axios
      .get(`products/${id}`)
      .then((res) => dispatch({
        type: FETCH_PRODUCT_SUCCESS,
        payload: res.data.data
      }))
      .catch((res) => dispatch({
        type: FETCH_PRODUCT_ERROR,
        /*payload: new Error(res.data.error),*/
        error: true
      }));
  }
于 2015-12-07T15:48:45.507 回答