Redux implementation popup case

To achieve the effect, click the display button to appear a pop-up box, click the close button to hide the pop-up box

  1. Create a popup component SRC/Components/modal. js, and introduce the APP component in index.js to display counters and popup components in 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>According to</button>
        <button>hidden</button>
        <div  style={styles}></div>
    </div>
}
Copy the code
  1. The popup component shows that hidden is a state, so we store it in the store, we call it show, because we need to start the action to change the state in the store we need to create modal.actions.js to store the control to show hidden actions, Let’s define the show and hide type of aciton as constants for easy import
// 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.// Added control to modal display hidden display state, which is hidden by default
    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
    }
}
Copy the code
  1. So we need to map that state to the props property. Because the show state is the same name as the show method, we need to alias the show state. The method that executes dispatch submit Actions is mapped to props using the bindActionCreators method
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'.// Add control to show hidden CSS styles
        display: showState ? 'block' : 'none'
    }
    return <div>
        <button onClick={show}>According to</button>
        <button onClick={hide}>hidden</button>
        <div  style={styles}></div>
    </div>
}
// Map to props to display the Props state
const mapStateToProps = state= > {
    return {
        showState: state.show
    }
}
// Map the submit Actions method to the component props
const mapDispacthToProps = dispatch= > bindActionCreators(modalActions, dispatch)
export default connect(mapStateToProps,mapDispacthToProps)(Modal)
Copy the code

Through the above, we found that the number in the counter component disappeared after clicking show and hide. Because we did not return the state of the counter in the show and hide method, the state was lost. We need to replace the original state when changing the state

  1. Fill in the original state
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
    }
}
Copy the code

At this time, our counter and popup components were normal, but we found that the Reducer function was becoming bloated with more and more changeable actions, and would become unmainable after more and more states

Split reducer function

In the case of counter and pop-up box, in the reducer function, we matched both actions in the counter case and actions in the pop-up case, so the code in the Reducer will become bigger and bigger, so we split the reducer next. We need to use the combineReducers method to split reducer. This method requires us to pass an object which is a state object and the return value is the merged reducer

  1. Create the SRC/store/reducers/modal. Reducers. Js file, the reducer of the pop-up box
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
    }
}
Copy the code
  1. Create the SRC/store/reducers/root. Reducers. Js file, is used to merge the counter with pop-up box reducer
import { combineReducers } from 'redux'
import CounterReducers from './counter.reducers'
import ModalReducers from './modal.reducers'

// Requires us to pass an object that is a state object
Counter: {count: 0} modaler: {show: false}
export default combineReducers({
    counter: CounterReducers,
    modaler: ModalReducers
})
Copy the code
  1. Since the state structure was changed when combineReducers merged reducer, we need to change the way of obtaining state in the component
// src/components/Count.js
const mapStateProps = ({ counter }) = > ({
    count: counter.count,
    a: '1'
})
// src/components/Modal.js
const mapStateToProps = ({ modaler }) = > {
    return {
        showState: modaler.show
    }
}
Copy the code