解体->升级,React+Redux全面来袭,小黑盒组件完成蜕变

1,032 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

前言

三周前,我写了一个关于小黑盒组件开发的React项目,经过一段时间的学习,这个项目终于迎来了更新!其实鸽了好久
这次更新的主要内容就是增加了redux,在完善小黑盒1.0的功能的同时增加了一些页面与功能,另外增加了几个可以优化的地方。
没看过上一个版本的同学可以先去考个古,传送门在这里--> 小黑盒1.0

Redux

什么是Redux?

Redux 是一个独立专门用于做状态管理的 JS 库(不是 react 插件库),它可以在很多的框架中使用,但是基本上是与React配合使用。它的作用就是集中式管理多个组件的状态。

Redux工作流程

React Components用户想要修改某个组件中的状态 --> Action Creators转发一个action --> Store(在此处起一个桥梁作用) --> Reducers接收传入的State以及action --> Reducers处理完成后将新的State传入Store --> Store将state变化重新渲染到组件上。
至此,组件完成了一次状态更新。(结合下图理解效果更佳) Redux工作流程.webp

在本项目中使用Redux

对于新手来说,在项目中设计Redux的过程是繁琐的,在这里我参考了社区大佬神三元的开源项目《React打造精美WebApp》中的方法。
那么,现在就来看看我是怎么在本项目中设计Redux的把。

  1. 引入Provider,用于connect数据的传递
    <Provider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </Provider>
  1. 建立总仓库Store
    index.js

    • composeEnhancers : 在浏览器中使用Redux DevTools调试插件
    import { createStore, compose, applyMiddleware } from 'redux'
    import thunk from 'redux-thunk'
    import reducer from './reducer'
    
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    
    const store =  createStore(reducer, composeEnhancers(applyMiddleware(thunk)))
    
    export default store;
    

    reducer.js: 集合了所有子仓库的reducer

    import { combineReducers } from "redux";
    
    import { reducer as allreducer } from '../pages/Home/All/store/index'
    import { reducer as storehousereducer } from '../pages/StoreHouse/store/index'
    import { reducer as searchreducer } from '../pages/Search/store/index'
    
    
    export default combineReducers ({
        all: allreducer,
        storehouse:storehousereducer,
        search: searchreducer
    })
    
  2. 在组件中使用connect将UI组件和容器组件连接起来

const mapStateToProps= (state) => {
    return {
        gameRecommendList: state.storehouse.gameRecommendList,
        enterLoading: state.storehouse.enterLoading,
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        getGameRecommendListDispatch() {
            dispatch(actionCreators.getGameRecommendList())
        }
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(StoreHouse)
  1. 在组件中建立子仓库
    index.js: 将子仓库与总仓库联系在一起

    import reducer from './reducer'
    import * as actionCreators from './actionCreators'
    import * as constants from './constants'
    
    export {
        reducer,
        actionCreators,
        constants
    }
    

    reducer.js

    import * as actionTypes from './constants'
    
    const defaultState = {
        gameRecommendList: [],
        ...
    }
    
    export default (state = defaultState, action) => {
        switch (action.type) {
            case actionTypes.CHANGE_GAMERECOMMENDLIST: 
                return {
                    ...state,
                    gameRecommendList: action.data
                }
            ...
            default:
                return state;
        }
    }
    

    actionCreators.js

    import { getGameRecommendListRequest } from '../../../api/request'
    import * as actionTypes from './constants'
    
    export const changeGameRecommendList = (data) => ({
        type: actionTypes.CHANGE_GAMERECOMMENDLIST,
        data: data
    })
    
    export const getGameRecommendList = () => {
        return (dispatch) => {
            getGameRecommendListRequest()
                .then(data => {
                    dispatch(changeGameRecommendList(data.data)),
                    dispatch(changeEnterLoading1(false))
                })
        }
    } 
    ...
    
    

    constants.js: 定义type

    export const CHANGE_GAMERECOMMENDLIST = "CHANGE_GAMERECOMMENDLIST"
    

在经历这些磨难后,我们的Redux的初步设计算是完成了。

项目更新内容

底部导航栏

增加了底部导航栏,效果如下

Footer.gif

游戏库页面开发

增加了游戏库页面,效果如下

游戏库页面开发.gif

搜索页面开发

增加了搜索页面(部分功能完善中),在这里我使用了CSSTransition使搜索页面弹出来的时候有一个过渡效果,优化了用户体验。效果如下

search.gif

loading状态升级

之前页面切换时的loading状态太过简单了,于是我使用了三元大佬项目中现成的loading状态,自己做了一些小改动,效果如下

loading v2.0.gif

优化

图片懒加载

当我们向后端请求数据的时候需要一定的时间,而图片等资源加载更加耗时,所以为了更好的而用户体验,我选择了使用图片懒加载,优先加载可视区域的内容,其他部分等进入了可视区域再加载,从而提高性能。效果如下

pic_lazyload.gif

React.memo

使用React.memo 包装一个组件,某些情况下会通过缓存来提升性能。React.memo 会检查 props 有无变化,如果没有变化,React会跳过render阶段,直接返回缓存的结果,从而提升性能。

export default connect(mapStateToProps,mapDispatchToProps)(React.memo(Search))

总结

对于一些小项目来说使用Redux是得不偿失的,因为需要管理的状态不会特别多,但是项目一但做大了,需要管理的状态特别多,那么Redux一定能助我们一臂之力。
本文是我最近一段时间对Redux的理解,希望正在看的各位能够有所收获,如果有错误也欢迎各位指出。各位看官不介意的话给本文点点赞也是可以的。😀

本文只给出了一些关键代码,全部代码地址如下(已开源):
项目地址: gitee地址github地址