【问题标题】:How to change the state of the child component?如何改变子组件的状态?
【发布时间】:2021-09-08 20:41:57
【问题描述】:

我正在使用 react 创建一个简单的应用程序,我有两个组件:Form 和 Modal。提交表单时应打开模态框。如何改变 Modal 组件的状态来实现这一点?

这是 Form.js 组件的代码:

import Modal from './Modal'

export default function Form() {
  const handleSubmit = (e) => {
    e.preventDefault()
  }
  return (
    <form onSubmit={handleSubmit}>
      <SuccessModal />
      <div className='mt-1'>
        ...
    </form>
)}

这是 Modal.js 组件的代码:

export default function Modal() {
  const [open, setOpen] = useState(false)

  return (
    <Transition.Root show={open} as={Fragment}>
      <Dialog
        as='div'
        static
        open={open}
        onClose={setOpen}
      >
        ...
      </Dialog>
     </Transition.Root>

我试图将此状态作为属性传递,但我认为我做错了什么。如果有人能向我解释其工作原理,我将不胜感激。

【问题讨论】:

    标签: javascript reactjs react-props use-state


    【解决方案1】:

    您可以在 Form.js 中拥有模态状态,然后将状态作为道具传递给 Modal.js

    在表单提交时设置模态状态。

    Form.js

    import Modal from './Modal'
    
    export default function Form() {
      const [open, setOpen] = useState(false)
    
      const handleSubmit = (e) => {
        e.preventDefault()
        ...
        setOpen(true);
      }
      return (
       <>
        <form onSubmit={handleSubmit}>
          <SuccessModal />
          <div className='mt-1'>
            ...
        </form>
        {open && <Modal open={open} setOpen={setOpen} />}
        </>
    )}
    
    

    Modal.js

    export default function Modal({ open, setOpen }) {
    
      return (
        <Transition.Root show={open} as={Fragment}>
          <Dialog
            as='div'
            static
            open={open}
            onClose={setOpen}
          >
            ...
          </Dialog>
         </Transition.Root>
    

    【讨论】:

    • 最简单最严格的前瞻实现
    • 感谢您的解决方案。只有一个语法错误。模态组件末尾缺少/ :) 应该是:{open &amp;&amp; &lt;Modal open={open} setOpen={setOpen} /&gt;}
    【解决方案2】:

    状态控制器useState 应该在父级中,而不是Modal

    然后你可以简单地使用一个 prop 来定义open 状态。

    我们在工作中这样做的一种方法是为它创建一个自定义挂钩:

    // stateless modal component
    export default function Modal({ open }) {
      return (
        <Transition.Root show={open} as={Fragment}>
          <Dialog
            as='div'
            static
            open={open}
            onClose={setOpen}
          >
            ...
          </Dialog>
         </Transition.Root>
    }
    
    // custom hook
    export function useModal({ initialState }) {
      const [open, setOpen] = useState(initialState)
    
      return {
        component: <Modal open={open} />,
        setOpen,
      }
    }
    
    // parent code
    import { useModal } from './Modal'
    
    export default function Form() {
      const modal = useModal(false)
      const handleSubmit = (e) => {
        e.preventDefault()
        modal.setOpen(true)
      }
      return (
        <form onSubmit={handleSubmit}>
          {modal.component}
          <div className='mt-1'>
            ...
        </form>
    )}
    
    

    【讨论】:

    • 自定义钩子的好用
    【解决方案3】:

    您可以尝试将子状态(模态)提升到父状态(表单)。 Refer this

    【讨论】:

      【解决方案4】:

      您不使用状态来显示或隐藏模态组件。使用道具。使用 props 组件将像这样工作:

      import Modal from './Modal'
      
      interface IFormProps {}
      interface IFormState {
        isModalOpen: boolean
      }
      
      export class Form extends React.Component<IFormProps, IFormState> => {
        state: IFormState = {
          isModalOpen: false,
        }
      
        const handleSubmit = (e): void => {
          this.setState({ isModalOpen: true })
          e.preventDefault()
        }
      
        const handleModalClose = (): boolean => {
          this.setState({ isModalOpen: false })
        }
      
        return (
          <form onSubmit={handleSubmit}>
            <Modal isOpen={this.state.isModalOpen} handleClose={this.handleModalClose} />
            <div className='mt-1'>
              ...
          </form>
      )}
      
      interface IModalProps {
        isOpen: boolean
        handleClose: () => boolean
      }
      
      interface IModalState {}
      
      export class Modal extends React.Compnent<IModalProps, IModalState> {
        const { isOpen, handleClose } = this.props
      
        return (
          <Transition.Root show={isOpen} as={Fragment}>
            <Dialog
              as='div'
              static
              open={isOpen}
              onClose={handleClose}
            >
              ...
            </Dialog>
           </Transition.Root>
      

      【讨论】:

        猜你喜欢
        • 2016-12-23
        • 2017-07-10
        • 2020-01-13
        • 1970-01-01
        • 2022-07-06
        • 2021-06-08
        • 2018-07-08
        • 2016-12-21
        相关资源
        最近更新 更多