如何使用React-Bootstrap与Redux实现Modal显示/隐藏功能
问题核心原因
- store创建位置错误:你将
createStore(showStore.reducer)直接写在了Example组件的函数体内,组件每次渲染都会重新初始化一个全新的store实例,之前dispatch修改的状态会全部丢失,永远返回初始值false。 - 没有监听store状态变更:原生Redux的store状态更新不会自动触发React组件重渲染,你仅调用
showStore.getState()拿到了初始值,后续store发生变化时组件感知不到,所以Modal的show属性不会更新。 - 未打通Redux和React的渲染逻辑:原生Redux没有和React的渲染机制绑定,要么手动订阅store变化触发重渲染,要么使用官方的react-redux库实现状态和组件的关联。
修复方案
步骤1:将store创建逻辑移到组件外部,全局仅初始化一次
import { createStore } from 'redux' const reducer = (state = false, action) => { switch (action.type) { case 'SHOW' : return true case 'HIDE' : return false default: return state } } // 全局只创建一次store const showStore = createStore(reducer)
步骤2:关联store状态和组件渲染
可以选择手动订阅的方案,或者用更简便的react-redux官方方案:
手动订阅实现
import { useState, useEffect } from 'react' const Example = () => { // 用本地state同步store状态,state变化会触发组件重渲染 const [show, setShow] = useState(showStore.getState()) useEffect(() => { // 订阅store变化,状态更新时同步到本地state const unsubscribe = showStore.subscribe(() => { setShow(showStore.getState()) }) // 组件卸载时取消订阅,避免内存泄漏 return unsubscribe }, []) const handleShow = () => { showStore.dispatch({type: 'SHOW'}) } const handleClose = () => { showStore.dispatch({type: 'HIDE'}) } return ( <> <Button onClick={handleShow}> Show modal </Button> <Modal show={show} 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
推荐的react-redux实现
安装react-redux后,用Provider包裹根组件,直接调用官方API即可,不需要手动处理订阅逻辑:
import { useSelector, useDispatch } from 'react-redux' const Example = () => { const show = useSelector(state => state) const dispatch = useDispatch() const handleShow = () => { dispatch({type: 'SHOW'}) } const handleClose = () => { dispatch({type: 'HIDE'}) } // 渲染逻辑和上面一致 }
内容的提问来源于stack exchange,提问作者csxo14
相关产品推荐
相关产品推荐

