最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从0搭建react框架项目之redux配置

    正文概述 掘金(丽丽里里丽丽里里丽丽)   2021-03-28   732

    从0搭建react框架项目之redux配置

    最近在整理项目的时候,从头把整个react项目的搭建顺了一遍,本文是redux、路由的配置,复制代码即可使用。

    首先创建一个react项目(my-app)

    从0搭建react框架项目之redux配置

    然后安装一系列redux、路由用到的插件

    从0搭建react框架项目之redux配置

    src/modle/index.js

    import React, { Component } from 'react';
    import { connect } from "react-redux";
    import { bindActionCreators } from 'redux';
    import store from "./../../store";
    import {
        action,
    } from './reducer.js'
    
    
    class Index extends Component {
        constructor(props) {
            super(props);
            this.state = store.getState();
        }
        render() {
            const {
                action: {
                    add_list,
                    change_input,
                },
                index: {
                    inputValue,
                    list,
                },
            } = this.props
            return (
                <div>
                    <div>
                        <input type="text" style={{ height: '17px' }}
                            value={inputValue}
                            onChange={e => change_input(e.target.value)} />
                        {/* action(add_list) 可直接用add_list() */}
                        <button style={{ verticalAlign: 'middle' }} onClick={() => add_list()}>添加</button>
                    </div>
    
                    <div>
                        <ul>
                            {list.map((item, index) => {
                                return (<li key={item + index}>{item}</li>);
                            })}
                        </ul>
                    </div>
                </div>
            );
        }
    }
    export default connect(
        state => ({
            index: state.index,
        }),
        dispatch => ({
            action: bindActionCreators(action, dispatch),
        })
    )(Index)
    

    首先创建一个Index组件,举了个小荔枝,大致效果如下图。

    从0搭建react框架项目之redux配置

    其中输入框的值inputValue、列表list这两个数据是存放在key为index的reducer中的。组件要想拿到state中的数据,需要在最外层的容器中把所有内容裹在Provider组件中,然后将创建的store(store的创建在下面,往下看)作为this.props传给Provider

    //src/index.js
    const App = () => {
      return (
        <Provider store={store}>
          <Comp/>
        </Provider>
      )
    };
    

    Provider组件内的任何一个组件,(比如这里的index组件),如果需要使用state中的数据,就必须是被connect过后的组件。 connect(mapStateToProps, mapDispatchToProps, mergeProps, options)它接收四个参数,通常我们只用到前面两个,想深入了解的朋友可以去官网look look。connect的第一个参数mapStateToProps(),这个函数允许我们把state中的数据作为props绑定到组件上。因为我们组件用到的只有state.index中的数据所以我们只需要输出组件需要的index的数据。

    const mapStateToProps = (state) => {
     return {
       index: state.index,
     }
    }
    

    connect的第二个参数是mapDispatchToProps,这个函数是将action作为this.props绑定到index组件上。

    const mapDispatchToProps = dispatch => ({
            action: bindActionCreators(action, dispatch),
        })
    
    • 本质上要触发action就必须在store上调用dispatch方法,但是为了不让index组件感知到dispatch的存在,该方法已经过包装,即调用该方法就会触发dispatch,如上述调用add_list这个action时 可直接用add_list()。
    • bindActionCreators函数可以自动把多个action创建函数绑定到dispatch()方法上。上述我们通过import {action} from './reducer.js' 把reducer.js中的change_inputadd_list两个action同时绑定到dispatch()上。

    src/module/index/reducer.js

    import {
        handleActions,
        createAction,
    } from 'redux-actions'
    const init_state = {
        inputValue: '',
        list: [
            '睁眼起床',
            '下床刷牙',
            '穿衣出门',
        ],
    }
    const index_setter = createAction('index_setter')
    // 隐射关系把原来的state映射成组件中的props属性
    export const action = {
        change_input: payload => (dispatch, get_state) => {
            dispatch(
                index_setter({
                    inputValue: payload,
                })
            )
        },
        add_list: payload => (dispatch, get_state) => {
            const state = get_state()
            const module_state = state['index']
            let list = module_state.list
            list.push(module_state.inputValue)
            dispatch(
                index_setter({
                    list: list,
                    inputValue: '',
                })
            )
        }
    }
    export default handleActions({
        [index_setter]: (state, { payload }) => ({
            ...state,
            ...payload,
        }),
    }, init_state)
    
    • createAction函数:创建一个index_setter,返回一个action工厂。
    • handleActions函数:处理action的操作,返回一个reduce。接收三个参数,第一个参数是action工厂,即index_setter;第二个参数是改变store的state的函数,大家不要被{[index_setter]:(){}}的写法吓住,就是把属性写成变量了而已;第三个参数是当store的state啥也没有的时候给定一个初始的state。
    var reducer = handleActions({
        [index_setter]: (state, { payload }) => ({
            ...state,
            ...payload,
        }),
    }, init_state)
    

    src/reducer.js

    import {
        combineReducers,
    } from 'redux'
    import index from './module/index/reducer'
    import second from './module/second/reducer'
    
    const app_reducer = combineReducers({
        index,
        //second, //本次例子中没有提到这个reducer。
    })
    const rootReducer = (state, action) => {
        return app_reducer(state, action)
    }
    export default rootReducer
    

    combineReducers函数作用是整合所有的reducer。我们的store只有一个,而reducer可以有很多个,他们通过key值(即上面的index、second)来区分,各自的reducer服务于自己的state。

    src/store.js

    import {
        createStore,
        applyMiddleware,
    } from 'redux'
    import rootReducer from './reducer.js'; // 相当于仓库管理员
    import thunk from 'redux-thunk'
    import logger from 'redux-logger'
    const env = 'development' // development production
    let enhancer
    if (env === 'production') {
        enhancer = applyMiddleware(thunk)
    } else {  //测试环境
        enhancer = applyMiddleware(thunk, logger)
    }
    const store = createStore(rootReducer,{}, enhancer) //创建一个store
    export default store
    
    • 使用createStore()创建一个store商店,createStore接收三个参数,第一个是reducer,第二个是初始值state,第三个是中间插件enhancer。applyMiddleware()接收多个中间插件,并返回一个enhancer函数。
    • logger中间插件可以在浏览器中console打印出我们的state变化,以及整个store,在测试中对调试非常有用。

    src/router.js 配置路由

    import React, {
        Component,
    } from 'react'
    import {
        HashRouter,
        Route,
        Redirect,
    } from 'react-router-dom'
    import loadable from 'react-loadable'
    // import Index from './module/index'
    import Second from './module/second'
    const Index = loadable({
        loader: () => import('./module/index'),
        loading() {
            return <div>正在加载</div>
        },
    })
    class Router extends Component {
        render() {
            return (
                <HashRouter>
                    <Route exact path='/' render={() => <Redirect to='/home'/>}/>
                    <Route path='/home' component={Index}/>
                    <Route path='/second' component={Second}/>
                </HashRouter>
            )
        }
    }
    export default Router
    
    • 路由配置很好理解啦,按照官网一步步配置就OK了。上面引入index组件我用到的react-loadable去引入,loadable是一个高阶组件,用来轻易的在组件层里面拆分bundle,我们试想一下,一个庞大的项目,会由很多个组件组成,加载js的速度也会变慢,所以我们可能会在某个重要的组件使用异步加载,加载组件之前先让用户知道你正在加载中,组件加载成功之后再渲染组件,很好的避免了打开页面会白屏一段时间。
    • Redirect组件的作用是重定向,exact是完全匹配,即路由完全一致时才会去加载该组件。

    src/index.js 项目入口文件

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { Provider } from "react-redux"; // 引入Provider组件
    import store from "./store";
    import Root from './router'
    
    ReactDOM.render(
      <Provider store={store}>
        <Root />
      </Provider>,
      document.getElementById('root')
    )
    

    最后进行入口文件的配置引入就OK啦。


    起源地下载网 » 从0搭建react框架项目之redux配置

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元