最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 使用react+redux实现弹出框案例

    正文概述 掘金(开水泡饭)   2021-06-02   267

    redux 实现弹出框案例

    实现效果,点击显示按钮出现弹出框,点击关闭按钮隐藏弹出框

    1. 新建弹出框组件 src/components/Modal.js, 在index.js中引入app组件,在app中去显示计数器和弹出框组件
    function Modal ({ showState, show, hide }) {
        const styles = {
            width: 200,
            height: 200,
            position: 'absolute',
            top: '50%',
            left: '50%',
            marginTop: -100,
            marginLeft: -100,
            backgroundColor: 'skyblue',
        }
        return <div>
            <button>显示</button>
            <button>隐藏</button>
            <div  style={styles}></div>
        </div>
    }
    
    1. 弹出框组件显示隐藏是一个状态,所以我们存储到store中,命名为show,因为需要出发action来修改store中的状态所系我们需要创建modal.actions.js文件,来存储控制显示隐藏的action,我们还是把显示与隐藏aciton的type定义为常量方便导入使用
    // src/store/const/modal.const.js
    export const SHOWMODAL = 'showModal'
    export const HIDEMODAL = 'hideModal'
    
    // src/store/actions/modal.actions.js
    import { SHOWMODAL, HIDEMODAL} from './../const/modal.const'
    
    export const show = () => ({type: SHOWMODAL})
    export const hide = () => ({type: HIDEMODAL})
    
    // src/store/reducers/counter.reducers.js
    import { INCREMENT, DECREMENT } from './../const/counter.const'
    import { SHOWMODAL, HIDEMODAL } from './../const/modal.const'
    
    const initialState = {
        count: 0,
        // 增加控制modal 显示隐藏显示的状态,默认为隐藏状态
        show: false
    }
    // eslint-disable-next-line import/no-anonymous-default-export
    export default (state = initialState, action) => {
        switch (action.type) {
            case INCREMENT:
                return {
                    count: state.count + action.payload
                }
            case DECREMENT:
                return {
                    count: state.count - action.payload
                }
            case SHOWMODAL:
                return {
                    show: true
                }
            case HIDEMODAL:
                return {
                    show: false
                }
    
            default:
                return state
        }
    }
    
    1. 弹框的显示隐藏状态用display属性控制所以我们需要把状态映射到props属性中,因为show状态与show显示方法重名了,所以给show状态起一个别名,利用 bindActionCreators 方法把 执行 dispatch 提交actions的方法映射到props中
    import React from 'react'
    import { connect } from 'react-redux'
    import * as modalActions from './../store/actions/modal.actions'
    import { bindActionCreators } from 'redux'
    
    function Modal ({ showState, show, hide }) {
        const styles = {
            width: 200,
            height: 200,
            position: 'absolute',
            top: '50%',
            left: '50%',
            marginTop: -100,
            marginLeft: -100,
            backgroundColor: 'skyblue',
            // 增加控制显示隐藏的css样式
            display: showState ? 'block' : 'none'
        }
        return <div>
            <button onClick={show}>显示</button>
            <button onClick={hide}>隐藏</button>
            <div  style={styles}></div>
        </div>
    }
    // 映射显示英藏状态到props中
    const mapStateToProps = state => {
        return {
            showState: state.show
        }
    }
    // 把提交actions方法映射到组件props中
    const mapDispacthToProps = dispatch => bindActionCreators(modalActions, dispatch)
    export default connect(mapStateToProps,mapDispacthToProps)(Modal)
    

    通过上面我们发现在点击显示与隐藏之后计数器组件中的数字不见了,因为我们在执行显示与隐藏的方法中并没有返回 计数器的状态所以这个状态丢失掉了,我们需要在更改状态的时候去补上原有的状态

    1. 补上原有状态
    export default (state = initialState, action) => {
        switch (action.type) {
            case INCREMENT:
                return {
                    ...state,
                    count: state.count + action.payload
                }
            case DECREMENT:
                return {
                    ...state,
                    count: state.count - action.payload
                }
            case SHOWMODAL:
                return {
                    ...state,
                    show: true
                }
            case HIDEMODAL:
                return {
                    ...state,
                    show: false
                }
    
            default:
                return state
        }
    }
    

    这个时候我们的计数器与弹出框组件都已经正常了,但是我们发现reducer函数随着actions动作越来越多变的越来越臃肿,在状态越来越多以后将会变得无法维护

    拆分reducer 函数

    在计数器与弹出框案例中,在reducer函数中,我们既匹配到了计数器案例中的actions,又匹配到了弹出框案例中的actions 这样reducer中的代码将会越来越庞大,越来越臃肿,所以我们接下来拆分reducer,拆分reducer我们需要用到 combineReducers 方法,这个方法要求我们传递一个对象 这个对象是状态对象,返回值是合并后的reducer

    1. 创建 src/store/reducers/modal.reducers.js 文件,把弹出框的reducer抽离出来
    import { SHOWMODAL, HIDEMODAL } from './../const/modal.const'
    
    const initialState = {
        show: false
    }
    
    // eslint-disable-next-line import/no-anonymous-default-export
    export default (state = initialState, action) => {
        switch (action.type) {
            
            case SHOWMODAL:
                return {
                    ...state,
                    show: true
                }
            case HIDEMODAL:
                return {
                    ...state,
                    show: false
                }
    
            default:
                return state
        }
    }
    
    1. 创建src/store/reducers/root.reducers.js 文件,用于合并计数器与弹出框的reducer
    import { combineReducers } from 'redux'
    import CounterReducers from './counter.reducers'
    import ModalReducers from './modal.reducers'
    
    // 要求我们传递一个对象 这个对象是状态对象
    // 这样写了之后 状态的结构将是这样 counter: { count: 0 } modaler: { show: false }
    export default combineReducers({
        counter: CounterReducers,
        modaler: ModalReducers
    })
    
    1. 因为使用 combineReducers 合并reducer的时候改变了state的结构所以我们需要在组件中去更改获取state的方式
    // src/components/Count.js
    const mapStateProps = ({ counter }) => ({
        count: counter.count,
        a: '1'
    })
    // src/components/Modal.js
    const mapStateToProps = ({ modaler }) => {
        return {
            showState: modaler.show
        }
    }
    

    起源地下载网 » 使用react+redux实现弹出框案例

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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