我有一个呈现react-modal
的组件,我的问题是react-modal
无法打开。 modalFileNameOpen
useState
属性设置不正确。
const [modalFileNameOpen, setmodalFileNameOpen] = useState(false)
const handleFileNameChangeClick = () => {
console.log(modalFileNameOpen) // set to false
setmodalFileNameOpen(true) // this does not set the `modalFileNameOpen` to true.
console.log(modalFileNameOpen) // is still false
}
return (
<div className="container-fluid">
<input type="button" className="btn" onClick={handleFileNameChangeClick} value="Rename File"></input>
<ModalFileName modalFileNameOpen={modalFileNameOpen} />
</div>
)
我还有另一个组成部分ModalFileName
import React, { useState } from 'react';
import Modal from 'react-modal';
Modal.setAppElement('#root');
const ModalFileName = ({ modalFileNameOpen }) => {
const [modalIsOpen, setModalIsOpen] = useState(modalFileNameOpen)
return (
<Modal isOpen={modalIsOpen} onRequestClose={() => setModalIsOpen(false)}>
<div>
<h1>File Name Change</h1>
<div>
<button onClick={() => setModalIsOpen(false)}>Close</button>
</div>
</div>
</Modal>
)
}
export default ModalFileName;
答案 0 :(得分:1)
这是您似乎想要实现的目标的最小示例。
这是将状态拉到父级并将处理程序函数传递给子级的基本说明。在您的代码中,您试图通过基于父级的状态在子级中声明一个新状态来进行此操作,这会导致不必要的重复和可能的状态冲突。
我们声明了模态状态和设置器以及一个基本的处理函数:
const [openModal, setOpenModal] = useState(false);
const toggleModal = () => {
setOpenModal(!openModal);
}
然后,我们根据当前状态值有条件地渲染模态分量。如果openModal
为假,则渲染按钮以将其打开,否则渲染Modal组件,并将处理函数toggleModal
传递给它作为道具。
// if openModal is false render the button, else render our modal
{!openModal ?
<button type="button" onClick={toggleModal}>Open Modal</button>
: <Modal handler={toggleModal} />
}
如果渲染了模态,它将接收处理程序(在此处通过解构function Modal({handler}) {...
进行检索)并将其分配给模态上关闭按钮的onClick
。
function Modal({handler}) {
return (
<div className="modal" >
<p>I'm a modal</p>
<button type="button" onClick={handler}>Close Modal</button>
</div>
)
}
工作示例
body {
padding: 0;
margin: 0;
}
.container {
position: relative;
height: 100vh;
width: 100vw;
background: gray;
}
.modal {
height: 50vh;
width: 50vw;
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
background-color: aqua;
}
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<div id="App"></div>
<script type="text/babel">
const {useState} = React;
function App() {
const [openModal, setOpenModal] = useState(false);
const toggleModal = () => {
setOpenModal(!openModal);
}
return (
<div className="container">
{!openModal ?
<button type="button" onClick={toggleModal}>Open Modal</button>
: <Modal handler={toggleModal} />
}
</div>
)
}
function Modal({handler}) {
return (
<div className="modal" >
<p>I'm a modal</p>
<button type="button" onClick={handler}>Close Modal</button>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('App'));
</script>
一些笔记
如果在console.log()
通话之前和之后setOpenModal()
,您将获得与问题相同的结果;它将打印出与输入渲染时相同的值。如果不存在问题,则说明您已经改变了状态。从Docs
请不要直接更改this.state,因为之后调用setState()可能会替换您所做的更改。将this.state视为不可变。
const [openModal, setOpenModal] = useState(false);
const toggleModal = () => {
console.log(openModal); // prints the value of openModal on entering render
setOpenModal(!openModal); // sets openModal to !openModal
console.log(openModal); // prints the value of openModal on entering render
}
此外,您可能希望将参数传递给传递的处理程序(可以说,close
按钮应始终将openModal
设置为false
,而不希望切换以将其关闭)。 / p>
为此,您只需在处理函数中接受一个参数即可。
const toggleModal = (newState) => {
setOpenModal(newState);
}
并将其传递给您的onClick
通话。
<button type="button" onClick={() => toggleModal(true)}>Open Modal</button>
function Modal({handler}) {
return (
<div className="modal" >
<p>I'm a modal</p>
<button type="button" onClick={() => handler(false)}>Close Modal</button>
</div>
)
}