ZoeyYoung / blog

博客
1 stars 0 forks source link

构建一个 React Redux CRUD 应用的 STEP #46

Open ZoeyYoung opened 8 years ago

ZoeyYoung commented 8 years ago

A Guide For Building A React Redux CRUD App

不错的总结,大概在创建一个功能模块的时候都要有这几个步骤,记录下几个问题

STEP 1 — Write Detailed Mocks For Each Page And Phases.

用到的软件:balsamiq-mockups

Mac 下可以用 brew cask 安装:brew cask install balsamiq-mockups

因为所有页面都采用AJAX请求来加载数据,因此都同时需要设计“Success(成功)”,"Loading(加载中)","Error(错误)"阶段的页面

STEP 2 — Divide Each Page Into Components

拆分组件通常比较简单

Redux Terms

PATTERN: Dealing With Async Actions

在处理异步请求时,通常具有如下的模式:

Initial State

{postsList:{posts:[], loading:false, error:null}}

Actions

1.“FETCH_OBJ”(for loading) 加载数据,设置加载中状态

{postsList:{posts:[], loading:true, error:null}}

2.“FETCH_OBJ_SUCCESS” 数据请求成功时分发

{postsList:{posts:[post1, post2], loading:false, error:null}}

3.“FETCH_OBJ_FAILURE” 数据请求失败时分发

{postsList:{posts:[], loading:false, error:{err: "Error Msg"}}}

4.“OBJ_RESET”(to cleanup dirty previous state)

{postsList:{posts:[], loading:false, error:null}}

只有一个小问题,就是如何区分是无数据,还是未加载?业务可能需要在无数据时显示特定的提示。追加一个数据是否为空的字段?扩展 loading 状态?

STEP 3 — List State and Actions For Each Component (AND For Each Phase)

列出所有可能改变组件展示的状态作为 States,并确定初始 state,确定可能的 Actions

这步通常大概一下就可以了

STEP 4 — Create Action Creators For Each Action

STEP 5 — Write Reducers For Each Action

这两步注意到一点,就是异步请求没有使用redux-thunk,在Container中分别使用了三个 Action Creator :

export function fetchPosts() {
  const request = axios({
    method: 'get',
    url: `${ROOT_URL}/posts`,
    headers: []
  });

  return {
    type: FETCH_POSTS,
    payload: request
  };
}

export function fetchPostsSuccess(posts) {
  return {
    type: FETCH_POSTS_SUCCESS,
    payload: posts
  };
}

export function fetchPostsFailure(error) {
  return {
    type: FETCH_POSTS_FAILURE,
    payload: error
  };
}

如果使用redux-thunk,就可以组合成下面的一个 ActionCreator :

export function fetchPosts() {
  return dispatch => {
    dispatch({
      type: FETCH_POSTS,
    });
    axios({
      method: 'get',
      url: `${ROOT_URL}/posts`,
      headers: []
    }).then(response => {
      if (!response.error) {
        return dispatch({
          type: FETCH_POSTS_SUCCESS,
          payload: response
        });
      }
      dispatch({
        type: FETCH_POSTS_FAILURE,
        payload: error
      });
    });
  };
}

Redux Term: “Presentational” and “Container” Components

STEP 6 — Implement Every Presentational Component

实现所有展示型组件

STEP 7 — Create Container Component For Some/All Presentational Component

创建容器组件

STEP 8 — Finally Bring Them All Together

之前把 containers 理解成 pages 应该是错误的,一个 page 通常是由多个 containers 组成的

由于这个错误理解,把一些本应该是 container 的东西放到了 components 中 :dizzy_face:


有一定经验后,现在大概步骤看起来都很简单,不过在不熟悉之前还是走了不少弯路的