从子级更改父级状态(两者均为功能组件)

时间:2020-03-14 03:27:08

标签: javascript reactjs next.js react-functional-component

以下问题的布局如下:

.
├── components
│   ├── ModalPolicy.js
│   ├── Footer
│       ├── index.js
├── pages
│   ├── index.js

我尝试在Footer/index.js上渲染Modal,但没有显示出来(就像我们在pages/index.js中的那个一样)。

因此,我不仅要在pages/index.js上渲染“ antd”模态,还要在pages/index.js上保持其“打开”方法的同时保持Modal状态(打开或关闭)通过Footer/index.js中的按钮进行操作,因为那是我们的页脚链接已存在的地方。

障碍是该问题涉及的所有组件都是功能组件,我在互联网上找到的每个解决方案都解决了父(或两者)都是类组件的情况。我要完成的任务的基本要点如下:

components / Footer / index.js

// imports..

const Footer = (openModalHandler) => {
  return (
    <section id="footer">
      <Layout>
        <div className="content">
          <a href="#footer" onclick={openModalHandler}>
            Policy
          </a>
        </div>
      </Layout>
    </section>
  )
}

pages / index.js (next.js)

// imports..
import Footer from '../components/Footer'
import ModalPolicy from '../components/ModalPolicy'

const Index = () => {
   const [openPolicy, setOpenPolicy] = React.useState(false)
   const closeModalPolicy = () => { /* Called by the Modal itself, don't bother with this */
      setOpenPolicy(false)     
   }
   const openModalHandler = () => { /* Called in Footer/index.js */
      setOpenPolicy(true)
   }

   return (
      <>
        <Some />
        <Other />
        <Stuff />
        <ModalPolicy open={openPolicy} onClose={closeModalPolicy} />
        <Footer openModalHandler={openModalHandler}
      </>
   )
}

components / ModalPolicy.js

// imports..
import { Modal, Button } from 'antd'

const ModalPolicy = ({ t, open, onClose }) => {
   return (
      <Modal
        title="Política de uso y privacidad"
        visible={open}
        onCancel={onClose}
        footer={null}
        width="fit-content">
          dangerouslySetInnerHTML={{
            __html: 
              `<h1>I'd really like to use dangerouslySetInnerHTML here</h1>
               <h2>It would make things a lot easier (assuming it won't look like crap on the browser)</h2>
              `
          }}
      </Modal>
  )
}

注意:我不确定我是否真的必须在pages / index.js上渲染Modal以使其正确显示。实际上,一般来说,我对React(因为我是一个后端开发人员)和浏览器端javascript缺乏经验。

如果有更简单的方法可以做到这一点,请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:1)

问题是您忘记从页脚组件的道具中破坏属性。现在,您不是在单击处理程序上传递单个函数,而是通过该函数传递对象。

const Footer = (openModalHandler)更改为const Footer = ({openModalHandler})

const Footer = ({openModalHandler}) => {
----------------^----------------^ // curly brackets to desturcture
  return (
    <section id="footer">
      <Layout>
        <div className="content">
          <a href="#footer" onClick={openModalHandler}>
------------------------------^------ // capitalize the c (camelCase properties)
            Policy
          </a>
        </div>
      </Layout>
    </section>
  )
}

在不破坏页脚组件的参数的情况下,react收到的props是带有密钥openModalHandler的对象

Play with it live if you'd like :)