簡體   English   中英

模態組件不會在自定義按鈕組件上呈現

[英]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 buttononClick 你能檢查一下嗎? 如果你認為它已經以正確的方式設置,那么你可以分享組件的代碼嗎?

第二個問題

是的,還有另一種方法可以做到這一點。 我認為它是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>
  );
}

演示

編輯 modal-component-does-not-render-on-a-custom-button-component

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM