0

I'm learning redux and I'm trying to get it to work with a react-bootstrap modal. I want the modal to show when the state in redux is set to true. However, when I try to get the state from redux the modal never shows even though the state changes to true.

It works fine when using regular state components (useState, setState).

Is there a reason the following code doesn't work?

Example React Component:

const Example = () => {
  const showStore = createStore(showStore.reducer)

  const handleShow = () => {
    showStore.dispatch({type: 'SHOW'})
  }
 
  const handleClose = () => {
    showStore.dispatch({type: 'HIDE'})
  }

  return (
    <>
      <Button onClick={handleShow}>
        Show modal
      </Button>

      <Modal show={showStore.getState()} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Modal title</Modal.Title>
        </Modal.Header>

        <Modal.Body>
          <Form>
            <Form.Label>Insert text</Form.Label>
            <Form.Control type="text" placeholder="Sample text" />

            <Modal.Footer>
              <Button onClick={handleClose}>
                Cancel
              </Button>
            </Modal.Footer>
          </Form>
        </Modal.Body>
      </Modal>
    </>
  
  )
}

export default Example
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

showStore:

const reducer = (state = false, action) => {
  switch (action.type) {
    case 'SHOW' :
      return true
    case 'HIDE' :
      return false
    default:
      return state
  }
}

export default { reducer }

1
  • why are you creating your store inside of your component? obviously, this state is not useful to you and cause such problem as you described. Commented Oct 9, 2021 at 12:53

1 Answer 1

2

With Redux the typical way would be to define the reducer and store in one file:

store/index.js:

import { createStore } from 'redux';

const modalReducer = (state = false, action) => {
  switch (action.type) {
    case 'SHOW':
      return true;
    case 'HIDE':
      return false;
    default:
      return state;
  }
};

const showStore = createStore(modalReducer);

export default showStore;

Your <Example> component is essentially the same with some minor changes indicated by the comments in the snippet below:

Example.js

function Example() {
  // Removed as store creation is now done in the store file
  // const showStore = createStore(showStore.reducer)

  // Extract data from the Redux store state and assign to const
  const showModal = useSelector((state) => state);
  
  const handleShow = () => {
    showStore.dispatch({ type: 'SHOW' });
  };

  const handleClose = () => {
    showStore.dispatch({ type: 'HIDE' });
  };

  return (
    <div>
      <Button onClick={handleShow}>Show modal</Button>

      // Changed to use const declared above
      <Modal show={showModal} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Modal title</Modal.Title>
        </Modal.Header>

        <Modal.Body>
          <Form>
            <Form.Label>Insert text</Form.Label>
            <Form.Control type="text" placeholder="Sample text" />

            <Modal.Footer>
              <Button onClick={handleClose}>Cancel</Button>
            </Modal.Footer>
          </Form>
        </Modal.Body>
      </Modal>
    </div>
  );
}

You then wrap the usage of your component with <Provider> (passing the store as a prop) so it becomes:

App.js

render(
  <Provider store={showStore}>
    <Example />
  </Provider>,
  document.getElementById('root')
);

making sure you import showStore:

import showStore from './store';

There's a working StackBlitz example here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.