iT邦幫忙

2022 iThome 鐵人賽

DAY 7
2

是的,昨天發文時因為壓底線,系統判定超過00:00,所以我按下發表文章後,沒有一如往常的在頁面上方看到綠色底色的恭喜字樣,反倒是立刻在右上角小鈴鐺處收到了一則通知,我斷賽了...

https://ithelp.ithome.com.tw/upload/images/20220924/20140920pY8MpOyroD.png
就...斷賽通知?

沒關係,我還是想盡力繼續完成這系列的分享,畢竟 React 是我第一個完整學習並且截至目前(擔任第10個月的前端工程師職位)已使用它開發過大約6個專案的前端框架。今天的文章主題來到了 React 資料庫,雖然資料流一直都不是我很拿手的項目,但是就算是寫前端,你必定要面對串接api,並呈現到頁面上的基本技能。我會稱它是一個前端資料庫,是因為你依然可以在前端的專案結構下定義一個存放靜態資料與call後端api資料的地方,我都稱這個地方為「stores」。

看過我上一篇文章的就知道,基本上我會把這個名為stores的資料夾區分三塊,依序介紹如下:

1. initialState.js(定義資料庫欄位)

就以這個檔案名稱的字面上定義來看,不難理解我就是拿它來當資料庫的起始值,假設你有一系列的頁面,分別為最新消息的列表、最新消息的詳細內容,那你可以初步將這個news的資料庫欄位先定義出來。

export const INITIAL_STATE = {
    newsList: [], // 最新消息的列表
    paging: {}, // 最新消息的列表頁碼
    newsInfo: {} // 最新消息的詳細內容
};

2. action.js(呼叫api的參數定義)

現在因為還沒有分享到串接api的部分,所以後面的敘述會不太理解沒關係,千萬不要氣餒,我會於後續兩篇再詳細解釋。
串接後端或外部api時,一定都會需要一些參數來做為你跟api溝通的條件,你可以在這個檔案先行定義你要怎麼給api參數的名稱,這邊要特別注意,參數名稱與順序擺放要跟後續篇章提到的saga function一樣,不然會有讀取不到的問題。
這些參數其實也沒有很難理解,舉例來說在列表頁常見的有頁碼、搜尋關鍵字或排序依據等等;在詳細頁裡就是像id這樣的資訊。

以下為整套CRUD的action範例:

import { createActions } from 'reduxsauce';

const { Types, Creators } = createActions({
    getNewsList: ['payload', 'callback', 'errorCallback'],
    getNewsListSuccess: ['payload', 'paging'],
    getNewsInfo:  ['id', 'callback', 'errorCallback'],
    getNewsInfoSuccess: ['payload', 'paging'],
    createNews:  ['payload', 'callback', 'errorCallback'],
    updateNews:  ['payload', 'callback', 'errorCallback'],
    deleteNews:  ['payload', 'callback', 'errorCallback'],
})

export const ActivityTypes = Types;
export default Creators;

3. reducer.js(用來處理call api回來的資料)

有時候後端給你的資料可能就是一大包,但你總不可能到呈現頁面的檔案上才去做整理吧?使用前端框架時,我覺得還是要養成習慣,資料處理建議還是在call api回來時馬上做完、存到資料庫(initialState.js)裡會比較好。

這邊的原理是,你call完api可能會得到一大包資料,你可以依照需求在第一時間(saga)就先拆解一點,成功後會依照你在action定義成功後要回傳的function裡,那你就可以在reducer裡再處理拿到的資料了。

這邊範例情境是:前端在畫面上需要key值,但後端給的是id

做法就是很簡單的 javascript 陣列處理,跑迴圈後把需要的值解構並賦值到你需要的欄位(這邊的舉例是key)裡。

import { INITIAL_STATE } from './InitialState';
import { createReducer } from 'reduxsauce';
import { NewsTypes } from './Actions';

export const getNewsListSuccess = (state, { payload, paging }) => {
  let temp = [];
  payload.map((item, index) => {
    temp.push({
      ...item,
      key: item.news_id,
    });
  });
  
  return {
    ...state,
    newsList: temp,
    paging: paging
  };
};

export const reducer = createReducer(INITIAL_STATE, {
  [NewsTypes.GET_NEWS_LIST_SUCCESS]: getNewsListSuccess,
})
今天的文章,要搭配明天的一起看,才會比較清楚唷!

上一篇
Day08:React 的組成-第二篇
系列文
你終究都要...學會 React ,何不一開始就看我一眼? 9
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
kk00915
iT邦新手 4 級 ‧ 2022-10-03 13:32:13

好可惜差一點點 系統真的hen不會做人!

我要留言

立即登入留言