0

I am rendering modal using react and redux. I've seen thousand of examples of how to create a modal, but none on how to fire it inside another component.

I took the same approach to render modals on redux on this question

My store is this:

export const store=createStore(
    rootReducer,
    compose(
        applyMiddleware(thunk)
    ))

And the main component:

class Main extends React.Component {
render () {
    return(
        <BrowserRouter>
            <Provider store={store} >
                <App/>
            </Provider>
        </BrowserRouter>
    )
}}

The app component is where I am guessing I should render the modal

class App extends React.Component {
render () {
    return(
        <div className="main-app">
            <Home />
            <Modal />
        </div>
    )
}}

But how can I update the state of this Modal component from within the components inside <Home >

My modal component looks like this:

import LoginModal from './LoginModal';

const MODAL_COMPONENTS = {
  'LOGIN': LoginModal
}

class ModalRoot extends React.Component {
    render() {
        const SpecificModal = MODAL_COMPONENTS[this.props.modal.modalType];
        if(!this.props.modal.showModal) return <SpecificModal />
        return null
    }
}
let mapStateToProps=state=>{
  return {
      modal: state.modal
  }
}
export default connect(mapStateToProps)(ModalRoot);

Which will be the best approach to change the state three (store) of my redux app to change the state of the modal?

Thanks

Hector
  • 147
  • 4
  • 11

1 Answers1

2

Suppose you want to trigger the modal by clicking a button in Home button. You can pass in dispatch function to Home using mapDispatchToProps and dispatch action that changes the state of modal from there.

actions.js

function changeModal(payload) {
  return {
    type: 'CHANGE_MODAL',
    payload,
  }
}

reducer

// below defines what's in store.modal
function modalReducer(state = {}, action) {
  switch(action.type) {
    case: 'CHANGE_MODAL':
       return {
          ...state, 
          ...action.payload
       }
    // ... rest of your code
  }
}

Home component

class Home extends Component {
  //... rest of logic
  changeModal = (modal) => {
    const currentModal = {
      showModal: true,
      modalType: modal,
    }
    this.props.changeModal({ modal: currentModal });
  }

  render() {
    // im using 2 buttons to trigger different modals, 
    return <div>
      <button onClick={() => this.changeModal('HOME')}>trigger home modal</button>
      <button onClick={() => this.changeModal('OTHER')}>trigger other modal</button>
    </div>
  }
}

const mapDispatchToProps = (dispatch) => ({
  changeModal: (payload) => dispatch(changeModal(payload))
});

// insert mapDispatchToProps as a second argument to connect
// home component may or may not have mapStateToProps
export default connect(mapStateToProps, mapDispatchToProps)(Home);

So when you press the button, the state.modal will change and it will show the modal depending on the new state.

Mμ.
  • 8,382
  • 3
  • 26
  • 36