新專案一次要產太多東西,所以就弄了一些偷懶用的小東東
使用 .vscode code sinnpets 定義文件格式
使用 (fn
+ ) control
+ Space
呼叫
文件使用描述 Action 格式
###_Action Title (Action_Name)
<details>
<summary>
API
```
GET api/...
```
</summary>
- **Body**
| KEY | TYPE | DESC |
| --- | ---- | ---- |
| | | |
- **Resp**
| KEY | TYPE | DESC |
| ------ | ------- | ------------ |
| state | Boolean | API 執行結果 |
| errmsg | String | 錯誤資訊 |
| data | null | |
</details>
redux 相關基底格式
action/
下的 action 根據路徑轉換 import 路徑
import action from '../../lib/createAction'
定義單一 action
export const action_name = 'action_name'
/**
* desc
* @param {string} param1 參數
*/
export const action_name = data => action(action_name, data)
定義 reducer
import * as actions from '../../actions'
const init = {
data: {},
isFetching: false,
errmsg: '',
}
export default function (
state = init, action) {
switch (action.type) {
// INIT_DATA
case actions[`INIT_DATA`]:
return init
default:
return state
}
}
定義 reducer 處理的 action case
// ACTION_NAME
case actions[`ACTION_NAME`]:
return {
...state,
}
container 基本配置,根據相對 containers/
的路徑 import 對應 component
import { connect } from 'react-redux'
import index from 'components/Permission/User/index'
import {
action_name
} from '../../../actions'
const mapStateToProps = (state) => {
const { account } = state.user
return {
account,
}
}
const mapDispatchToProps = {
action_name
}
export default connect(mapStateToProps, mapDispatchToProps)(index)
api 相關進階 redux 格式
定義 api 相關 action
export const get_action_name = 'get_action_name'
/**
* desc
* @param {string} param1 參數
*/
export const get_action_name = data => action(get_action_name, data)
export const get_action_name_succ = data => action(get_action_name_SUCC, data)
export const get_action_name_SUCC = 'get_action_name_SUCC'
export const get_action_name_fail = data => action(get_action_name_FAIL, data)
export const get_action_name_FAIL = 'get_action_name_FAIL'
用於 reducer 定義 api 相關 action case
// GET_ACTION_NAME
case actions[`GET_ACTION_NAME`]:
return {
...state,
errmsg: '',
isFetching: true,
}
case actions[`GET_ACTION_NAME_SUCC`]:
return {
...state,
data: action.data,
isFetching: false,
}
case actions[`GET_ACTION_NAME_FAIL`]:
return {
...state,
errmsg: action.errmsg,
data: action.data || init.data,
isFetching: false,
}
用於 reducer 定義不同 method 的 api 相關 action case
自行在外部先定義
ACTION
名稱,method 可選擇GET
,POST
,DELETE
,PUT
,PATCH
// POST
case actions[`POST_${ACTION}`]:
return {
...state,
errmsg: '',
isFetching: true,
}
case actions[`POST_${ACTION}_SUCC`]:
return {
...state,
data: action.data,
isFetching: false,
}
case actions[`POST_${ACTION}_FAIL`]:
return {
...state,
errmsg: action.errmsg,
data: action.data || init.data,
isFetching: false,
}
用於 saga/
,協助 import 相關檔案、function
import { take, call, put, select } from 'redux-saga/effects'
import * as actions from '../../actions'
import api from '../../lib/api'
定義 api function
/**
* desc
* @param {string} param1 參數
*/
export function fn_name({type, ...data}) {
return api({
cmd: `User/Login`,
method: 'GET',
data
})
}
於 sagas/index.js
定義 saga,使用 commonWorker 定義流程
yield takeLatest(actions.ACTION_NAME, (action) => commonWorker(action, api.function))
於 sagas/index.js
定義 saga,使用自訂 worker 定義流程
yield takeLatest(actions.ACTION_NAME, api.function)
自訂 saga worker
export function* fnName(action) {
const actionType = action.type.toLowerCase()
const res = yield call(api, action)
const succ = actions[`${ actionType }_succ`]
const fail = actions[`${ actionType }_fail`]
if (res.ok) {
yield put(succ(res.body))
yield put(actions.enqueue_snackbar({
message: `succ_msg`,
key: new Date().getTime(),
options: {
variant: 'success'
}
}))
}
else {
yield put(fail(res.body))
yield put(actions.enqueue_snackbar({
message: `errmsg`,
key: new Date().getTime(),
options: {
variant: 'error'
}
}))
}
}