[英]Modal component does not render on a custom button component
我正在嘗試在單擊按鈕時呈現自定義和動態模式。 例如,當單擊“游戲”按鈕時,我希望使用有關游戲的規范來呈現模式,當單擊“銀行”按鈕時,我希望模式中填充有關銀行的規范。
首先,當我將 onClick function 添加到自定義按鈕組件時,模態不會呈現。 但是,當我將 onClick function 放在常規按鈕上時,模式會呈現。 如何在任何組件上簡單地添加 onClick function 以呈現動態模態?
其次,我想用不同的數據填充每個模式。 例如,“游戲”按鈕將使用標題“游戲”等填充模態框。 我正在使用道具來做到這一點,但這是最好的解決方案嗎?
這是我到目前為止的代碼,但是當我將 onClick function 添加到組件時它被破壞了。
// Navbar.js
import { ModalContext } from '../contexts/ModalContext'
function Navbar() {
const [showModal, updateShowModal] = React.useState(false)
const toggleModal = () => updateShowModal((state) => !state)
return(
<ModalContext.Provider value={{ showModal, toggleModal }}>
<Modal
title="Title"
canShow={showModal}
updateModalState={toggleModal}
/>
</ModalContext.Provider>
)
// does not render a modal
<Button
onClick={toggleModal}
type="navItem"
label="Game"
icon="windows"
/>
// render a modal
<button onClick={toggleModal}>Show Modal</button>
)
}
import { ModalContext } from '../contexts/ModalContext'
// Modal.js
const Modal = ({ title }) => {
return (
<ModalContext.Consumer>
{(context) => {
if (context.showModal) {
return (
<div style={modalStyles}>
<h1>{title}</h1>
<button onClick={context.toggleModal}>X</button>
</div>
)
}
return null
}}
</ModalContext.Consumer>
)
}
// modalContext.js
export const ModalContext = React.createContext()
// Button.js
function Button({ label, type = 'default', icon }) {
return (
<ButtonStyle buttonType={type}>
{setIcon(icon)}
{label}
</ButtonStyle>
)
}
我認為<Button>
組件的onClick
道具沒有指向組件內實際HTML button
的onClick
。 你能檢查一下嗎? 如果你認為它已經以正確的方式設置,那么你可以分享組件的代碼嗎?
是的,還有另一種方法可以做到這一點。 我認為它是React Composition 。 您可以按以下方式構建模態:
<Modal
showModal={showModal}
updateModalState={toggleModal}
>
<div className="modal__header">{title}</div>
<div className="modal__body">{body}</div>
<div className="modal__footer">{footer}</div>
</Modal>
我認為這種模式會讓你更好地控制那個組件。
您沒有將onClick
道具傳遞給樣式按鈕組件。
給定樣式組件按鈕:
const ButtonStyle = styled.button``;
自定義Button
組件需要將所有按鈕道具傳遞給ButtonStyle
組件。
// Button.js
function Button({ label, type='default', icon, onClick }) {
return (
<ButtonStyle buttonType={type} onClick={onClick}>
{setIcon(icon)}
{label}
</ButtonStyle>
)
}
如果還有其他按鈕道具,那么您可以使用 Spread 語法將它們收集到單個 object 中,然后可以將其傳播到ButtonStyle
組件中。
// Button.js
function Button({ label, type = 'default', icon, ...props }) {
return (
<ButtonStyle buttonType={type} {...props}>
{setIcon(icon)}
{label}
</ButtonStyle>
)
}
對於第二個問題,我建議將打開/關閉/標題 state 與Modal
組件一起完全封裝在模態上下文提供程序中。
這是一個示例實現:
const ModalContext = React.createContext({
openModal: () => {},
});
const Modal = ({ title, onClose}) => (
<>
<h1>{title}</h1>
<button onClick={onClose}>X</button>
</>
)
const ModalProvider = ({ children }) => {
const [showModal, setShowModal] = React.useState(false);
const [title, setTitle] = React.useState('');
const openModal = (title) => {
setShowModal(true);
setTitle(title);
}
const closeModal = () => setShowModal(false);
return (
<ModalContext.Provider value={{ openModal }}>
{children}
{showModal && <Modal title={title} onClose={closeModal} />}
</ModalContext.Provider>
)
}
示例消費者設置/打開模式:
const OpenModalButton = ({ children }) => {
const { openModal } = useContext(ModalContext);
return <button onClick={() => openModal(children)}>{children}</button>
}
示例用法:
function App() {
return (
<ModalProvider>
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<OpenModalButton>Modal A</OpenModalButton>
<OpenModalButton>Modal B</OpenModalButton>
</div>
</ModalProvider>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.