如何解决React-Bootstrap中创建/编辑模态框显示冲突问题?
解决React-Bootstrap中Create User按钮误打开Edit Modal的问题
我正在使用React-Bootstrap和TypeScript构建CRUD应用,Users页面需要为Create User和Edit User按钮分别配置模态框。目前编辑按钮可正常打开Edit Modal,但点击Create User按钮时,打开的却是Edit Modal而非Create Modal。
现有代码
Users.tsx
const Users = (props: Props) => { const [userList, setUserList] = useState<IList[]>([]); const [show, setShow] = useState(false); const [selected, setSelected] = useState(Object); const [updatedItem, setUpdatedItem] = useState(); const getUsers = async () => {...}; useEffect(() => {...}, [updatedItem]); const handleShow = () => setShow(true); const closeHandler = () => setShow(false); const userHandler = async (user: any) => {...}; const updateHandler = async (user: any) => {...}; const handleEdit = (selected: any) => {...}; const createModal = ( <> <Modal show={show} onHide={closeHandler} className="modal"> <Modal.Header closeButton> <Modal.Title>Create User</Modal.Title> </Modal.Header> <Modal.Body> <UserForm userHandler={userHandler} closeHandler={closeHandler} updateHandler={updateHandler} formUpdate={false} userList={""} /> </Modal.Body> </Modal> </> ); const editModal = ( <> <Modal show={show} onHide={closeHandler} className="modal"> <Modal.Header closeButton> <Modal.Title>Edit User</Modal.Title> </Modal.Header> <Modal.Body> <UserForm userHandler={userHandler} closeHandler={closeHandler} updateHandler={updateHandler} formUpdate={true} userList={selected} /> </Modal.Body> </Modal> </> ); return ( <div> <Button variant="danger" type="button" onClick={handleShow}> Create User </Button> {createModal} {userList.length > 0 ? ( <UserTable deleteHandler={deleteHandler} handleEdit={handleEdit} userHandler={userHandler} closeHandler={closeHandler} updateHandler={updateHandler} userList={userList} /> ) : ( "" )} {editModal} </div> ); }; export default Users;
UserForm.tsx
type Props = { userHandler: (user: object) => void; userList: any; updateHandler: (user: object) => void; formUpdate?: boolean; closeHandler: () => void; }; class UserForm extends Component<Props, State> { componentDidUpdate() {...}; addUser = (e: any) => {...}; update = () => {...}; render() { return ( <div> <Form onSubmit={this.addUser}> ... <Modal.Footer> {this.props.formUpdate ? ( <> <Button variant="outline-secondary" className="modal-btn" onClick={this.props.closeHandler} > Cancel </Button> <Button variant="danger" className="modal-btn" type="button" onClick={this.update} > Edit User </Button> </> ) : ( <> <Button variant="outline-secondary" className="modal-btn" onClick={this.props.closeHandler} > Cancel </Button> <Button variant="danger" className="modal-btn" type="submit" onClick={this.addUser} > Create User </Button> </> )} </Modal.Footer> </Form> </div> ); } } export default UserForm;
问题原因
两个模态框共用了同一个show状态变量,点击Create User按钮时,show被设为true,导致Create Modal和Edit Modal同时显示。由于Edit Modal在DOM结构中位于Create Modal之后,会覆盖前者,看起来像是打开了Edit Modal。
解决方案
拆分模态框的显示状态,为每个模态框单独维护显示状态,具体修改步骤如下:
1. 替换统一的show状态为独立状态
将原来的单状态替换为两个独立的显示状态:
const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false);
2. 修改模态框的show属性
分别为两个模态框绑定对应的显示状态和关闭逻辑:
const createModal = ( <> <Modal show={showCreateModal} onHide={() => setShowCreateModal(false)} className="modal"> {/* 原有标题和内容保持不变 */} </Modal> </> ); const editModal = ( <> <Modal show={showEditModal} onHide={() => setShowEditModal(false)} className="modal"> {/* 原有标题和内容保持不变 */} </Modal> </> );
3. 更新按钮点击事件和关闭回调
- Create User按钮点击时打开Create Modal:
<Button variant="danger" type="button" onClick={() => setShowCreateModal(true)}> Create User </Button>
- 修改
handleEdit函数,打开Edit Modal并设置选中用户:
const handleEdit = (selectedUser: any) => { setSelected(selectedUser); setShowEditModal(true); };
- 为
UserForm传递对应模态框的关闭函数:- Create Modal中的
UserForm:
<UserForm userHandler={userHandler} closeHandler={() => setShowCreateModal(false)} updateHandler={updateHandler} formUpdate={false} userList={""} />- Edit Modal中的
UserForm:
<UserForm userHandler={userHandler} closeHandler={() => setShowEditModal(false)} updateHandler={updateHandler} formUpdate={true} userList={selected} /> - Create Modal中的
修改后的完整Users.tsx示例
const Users = (props: Props) => { const [userList, setUserList] = useState<IList[]>([]); const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [selected, setSelected] = useState<Object>({}); const [updatedItem, setUpdatedItem] = useState(); const getUsers = async () => {...}; useEffect(() => {...}, [updatedItem]); const userHandler = async (user: any) => {...}; const updateHandler = async (user: any) => {...}; const handleEdit = (selectedUser: any) => { setSelected(selectedUser); setShowEditModal(true); }; const createModal = ( <> <Modal show={showCreateModal} onHide={() => setShowCreateModal(false)} className="modal"> <Modal.Header closeButton> <Modal.Title>Create User</Modal.Title> </Modal.Header> <Modal.Body> <UserForm userHandler={userHandler} closeHandler={() => setShowCreateModal(false)} updateHandler={updateHandler} formUpdate={false} userList={""} /> </Modal.Body> </Modal> </> ); const editModal = ( <> <Modal show={showEditModal} onHide={() => setShowEditModal(false)} className="modal"> <Modal.Header closeButton> <Modal.Title>Edit User</Modal.Title> </Modal.Header> <Modal.Body> <UserForm userHandler={userHandler} closeHandler={() => setShowEditModal(false)} updateHandler={updateHandler} formUpdate={true} userList={selected} /> </Modal.Body> </Modal> </> ); return ( <div> <Button variant="danger" type="button" onClick={() => setShowCreateModal(true)}> Create User </Button> {createModal} {userList.length > 0 ? ( <UserTable deleteHandler={deleteHandler} handleEdit={handleEdit} userHandler={userHandler} updateHandler={updateHandler} userList={userList} /> ) : ( "" )} {editModal} </div> ); }; export default Users;
说明
通过为每个模态框单独维护显示状态,确保点击Create按钮时只有Create Modal被激活显示,点击Edit按钮时只有Edit Modal被激活,彻底解决了模态框重叠显示的问题。
内容的提问来源于stack exchange,提问作者Fluer2000
相关产品推荐
相关产品推荐

