日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Redux 一个还好的redux 实践吧

發布時間:2025/3/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redux 一个还好的redux 实践吧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

剛開始用redux 感覺它有點笨笨的;

因為重復代碼非常多啊;

以官方例子說吧:(并不是說官網例子不好,對剛起步用它的人來說,封裝太多反而難以理解)

1.對于store中的一個值的改變需要寫兩個方法也是有點啰嗦;

2.算上action中的type 和 和reducer中的switch,加起來每寫一個action都要寫3,4次相同或者類似的名字也是很煩的;

3.每次更新狀態都要 dispatch(action(xxx))或者手動封裝...


然后自己動手擼了一點小方法,改善了一下

這個實踐最后在組件中的使用如下:

假設有一個store模塊結構如下:

{ songSheet: {name: "推薦歌單", list: [], active: false, isFetching: false,...}, ...placeConf:{personal: {name: "私人FM", show: false,...},...} }復制代碼

然后再reducer的分支處理函數中如下設置:

setPlaceConfPersonalVis(state, action){return copy(state,{placeConf:{personal:{show: state.data}} })}復制代碼

然后mapDispatchToProps方法中這么寫 :

const mapDispatchToProps = dispatch => {const $actions = makeActions(dispatch);$action.setPlaceConfPersonalVis(true); return {...actions ,// ... 其他方法} }復制代碼

是的,簡化后使用就是這么簡單。

然后如下是各文件代碼:

reducers/index.js // 合并 各reducer模塊

import { combineReducers } from 'redux'; import cmusichome from './cmusichome'; export default combineReducers({cmusichome,// 這里可以放其他模塊的 reducer });復制代碼

reducers/cmusichome.js // 被 reducers/index.js引用 // 核心之一, 將reducer的分支方法拆分出去;

// 這個是分支處理函數 import cmusichomeFn from "./cmusichomeFn.js"; // 這里是reducer // 生成并更新store 的入口函數 const cmusichome = (state, action) => {// 初始化時, 沒有state 所以可以在這里設置 初始值state || (state= {songSheet: {name: "推薦歌單", list: [], active: false, isFetching: false,},songList: {name: "最新音樂", list: [], active: false, isFetching: false,},djprogramList: {name: "主播電臺", list: [], active: false, isFetching: false,},playList:{name: "歌曲列表", list: [], show: false, isFetching: false,},recmendList:{show: false, list:[]},placeConf:{personal: {name: "私人FM", show: false},recmend: {name: "每日推薦", show: false},songList: {name: "歌單", show: false},rankingList: {name: "排行榜", show: false},}});const curFn = cmusichomeFn[action.type];// 根據action 查找分支函數return curFn && curFn(state, action) || state;// 沒找到處理函數 則返回上一次的 state }; export default cmusichome;復制代碼

reducers/cmusichomeFn.js,// 節選,可以自己添加一些處理分支 被cmusichome.js引用

import tools from "../components/tools.js"; const {copy} = tools; export default {// 歌單updateSongSheet(state, action) {return copy(state, {songSheet: {list: action.data,}});},toggleSongSheetState(state, action){return copy(state, {songSheet: {active: !state.songSheet.active,}});},fetchSongSheet(state,action){return copy(state, {songSheet: {isFetching: action.data,}});}, };復制代碼

actions/index.js // 被views/Discover.js容器組件引用 // 核心之一,根據reducerFn的鍵名,創建同名action方法;

// 所有在 reducer 中使用的分支函數; import cmusichomeFns from "../reducers/cmusichomeFn"; // ...這里可以繼續引入其他模塊的分值函數// 根據reducer 分支函數名, 創建對應的 action 函數 // 這些action函數會接受一個值, 然后生成 返回{type: action名, data: 參數值}的方法; function makeReducerFnsIntoActions(reducerFns){const actions = {};Object.keys(reducerFns).forEach(item => actions[item] = data => ({type: item, data}));return actions; }; // 組合所有actions 作為 makeActions 內部需要轉化的actions const actions = {...makeReducerFnsIntoActions(cmusichomeFns),// ...這里可以繼續添加 分支函數 }; // 導出將 dispatch(action(val)) 轉化為 xxx.action(val) 模式的函數; // 可以在外界用 ...xxx 解構成 action(val); 接受 dispatch 作為參數; // 然后在 mapDispatchToProps 方法中 return { ...makeActions(dispatch), ... } // 就可以在 子組件中使用xxx.action(val) 真是極方便的; export default function makeActions(dispatch){function _(str,val){dispatch(actions[str](val));};const actionFn = {};Object.keys(actions).forEach(item=> actionFn[item] = val => _(item,val));return actionFn; }復制代碼

App.js // 含react-router / react-redux

import React from 'react'; import logo from '../images/logo.svg'; import './App.css'; import {HashRouter,Route} from 'react-router-dom'; import Discover from './Discover.js'; const App = () => (<HashRouter basename="/"><div className="App"><img src={logo} className="App-logo" alt="logo" /><audio src="" id="audio"></audio><Route path="/discover" component={Discover}/></div></HashRouter> ); export default App;復制代碼


views/Discover.js // 容器組件 // 被App.js 引用

import makeActions from '../actions'; import $http from "./../http/http.js"; import React, from 'react'; import { connect } from 'react-redux'; import Home from "./Home/Home.js"; const mapStateToProps = state => ({...state.cmusichome}); const mapDispatchToProps = dispatch => {const $actions = makeActions(dispatch);$http.personalized()(res => {$actions.updateSongSheet(res.result.map(item => ({name: item.name, img: item.picUrl, id: item.id,})))});return{...$actions,// 貌似到子組件 const {$action} = props;會好一些getPlayList: function (id) {$actions.fetchPlayList(true);$http.playlistDetail({id})(res=>{$actions.updatePlayList(res.playlist.tracks);$actions.togglePlayList(true);$actions.fetchPlayList(true);});},playASong(id){$http.songUrl({id})(res=>{const audio = document.querySelector("#audio");audio.src = res.data[0].url;audio.play();})},}}; export default connect(mapStateToProps, mapDispatchToProps)(Home);復制代碼

copy.js // 被 reducers/cmusichomeFn.js 引用 // 核心之一 // 深拷貝數組外的屬性 // 對于數組的操作是: 通過數組map返回新數組替換之前的數組,并不會直接引用傳入的數組或者原store中的值(為什么這么做我也不知道);

import type from "./type.js"; function _copy() {if(arguments.length) {const list = Array.prototype.map.call(arguments, item => item);const curObj = list.shift();Object.keys(curObj).forEach(item=>{const val = curObj[item];if(val !== undefined)this[item] = (type.isObject(val) && copy(this[item]||{},val)) ||(type.isArray(val) && val.map(item => item)) ||val;});return _copy.apply(this, list);} else return this; } function copy(){return _copy.apply({},arguments);} export default copy;復制代碼

type.js // 被 copy.js 引用

const getType = item => (Object.prototype.toString.call(item).slice(8, -1));getType.isNumber = item => getType(item) === 'Number'; getType.isString = item => getType(item) === 'String'; getType.isArray = item => getType(item) === 'Array'; getType.isObject = item => getType(item) === 'Object'; getType.isBoolean = item => getType(item) === 'Boolean'; getType.isNull = item => getType(item) === 'Null'; getType.isUndefined = item => getType(item) === 'Undefined'; getType.isFunction = item => getType(item) === 'Function'; getType.isDate = item => getType(item) === 'Date'; export default getType;復制代碼

demo 請移架?https://github.com/DeyaoCai/cmusic?


轉載于:https://juejin.im/post/5be3124951882516d1553181

總結

以上是生活随笔為你收集整理的Redux 一个还好的redux 实践吧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。