简体   繁体   English

如何在反应的组件中传递useState?

[英]How to pass useState amoung the components in react?

I have a register page and Modal component.我有一个注册页面和模态组件。 In register has a useState for visibility of the Modal.在寄存器中有一个用于模态可见性的useState I'm passing it as a prop to Modal.我将它作为道具传递给 Modal。 When the modal is closed how to change the useState value in the register page.当模态框关闭时如何更改注册页面中的useState值。

Register page:注册页面:

import React, { useState } from 'react'
import {
  CCard,
  CButton,
  CCardBody,
  CCardHeader,
  CCol,
  CForm,
  CFormInput,
  CFormLabel,
  CSpinner,
  CRow,
} from '@coreui/react'
import CIcon from '@coreui/icons-react'
import { cilSend } from '@coreui/icons'
import Alert from 'src/components/Alert'
import Modal from 'src/components/Modal'

const FormControl = () => {
  const [disabled, setDisabled] = useState(false)
  const [visible, setVisible] = useState(false)
  const [email, setEmail] = useState('')
  const [name, setName] = useState('')

  const handleAddMember = async () => {
    try {
      const data = { email, name }

      const _data = await fetch('http://localhost:4000/api/v1/member/register', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer ' + localStorage.getItem('token'),
        },
        body: JSON.stringify(data),
      })

      if (_data.status === 201) {
        setVisible(true)
        setDisabled(false)
      } else if (_data.status === 422) {
        setDisabled(false)
      } else {
        setDisabled(false)
        throw new Error()
      }
    } catch (err) {
      setDisabled(false)
    }
  }

  return (
    <CRow>
      <Modal visible={visible} message="Member added to your community successfully!" />
      <CCol xs={6}>
        <CCard className="mb-4">
          <CCardHeader>
            <strong>Add New Member</strong>
          </CCardHeader>
          <CCardBody>
            <p className="text-medium-emphasis small">
              Fill in the email address field and name field to add a new member to your community.
            </p>
            <CForm>
              <div className="mb-3">
                <CFormLabel>Email address:</CFormLabel>
                <CFormInput
                  type="email"
                  placeholder="name@example.com"
                  onChange={(e) => {
                    setEmail(e.target.value)
                  }}
                />
              </div>
              
              <div className="mb-3">
                <CFormLabel>Name:</CFormLabel>
                <CFormInput
                  type="text"
                  placeholder="Perera's Home"
                  onChange={(e) => {
                    setName(e.target.value)
                  }}
                />
              </div>
              
              <div className="mb-3">
                <CButton color="primary" disabled={disabled} onClick={() => handleAddMember()}>
                  {disabled ? (
                    <CSpinner component="span" className="me-2" size="sm" aria-hidden="true" />
                  ) : (
                    <CIcon icon={cilSend} className="me-2" />
                  )}
                  Submit
                </CButton>
              </div>
            </CForm>
          </CCardBody>
        </CCard>
      </CCol>
    </CRow>
  )
}

export default FormControl

Modal component:模态组件:

import React, { useState } from 'react'
import PropTypes from 'prop-types'
import { CButton, CModal, CModalBody, CModalFooter, CModalHeader, CModalTitle } from '@coreui/react'

const Modal = (props) => {
  const [visible, setVisible] = useState(props.visible)

  return (
    <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}>
      <CModalHeader>
        <CModalTitle>Success!</CModalTitle>
      </CModalHeader>
      <CModalBody>{props.message}</CModalBody>
      <CModalFooter>
        <CButton color="primary" onClick={() => setVisible(false)}>
          Close
        </CButton>
      </CModalFooter>
    </CModal>
  )
}

Modal.propTypes = {
  visible: PropTypes.bool,
  message: PropTypes.string,
}

export default React.memo(Modal)

You should have just one visible state member, either in the parent component or in the child ( Modal ), rather than having it in both places.您应该在父组件或子组件( Modal )中只有一个visible的 state 成员,而不是在两个地方都有它。

If you put it in the parent, you can pass it to the child just like any other prop:如果你把它放在父母中,你可以像任何其他道具一样将它传递给孩子:

return <Modal visible={visible} setVisible={setVisible}>{/*...*/}</Modal>

Modal 's code can then call props.setVisible with the appropriate flag.然后Modal的代码可以使用适当的标志调用props.setVisible

If you only want Modal to be able to hide itself (not show itself), you might instead pass a wrapper function that calls setVisible(false) :如果您希望Modal能够隐藏自己(不显示自己),则可以改为传递调用setVisible(false)的包装器 function :

const hide = useCallback(() => setVisible(false), [setVisible]);
//                Optional, see below −−−−−−−−−−−−−^^^^^^^^^^
// ...
return <Modal visible={visible} hide={hide}>{/*...*/}</Modal>

...and then Modal 's code calls hide() to hide the modal. ...然后Modal的代码调用hide()来隐藏模式。

(Making setVisible a dependency in the useCallback call is optional; state setter functions are stable ; they don't change during the lifetime of the component. Some linters aren't quite smart enough to realize that and may nag you if you don't include it, but most are smarter than that.) (在useCallback调用中使setVisible成为依赖项是可选的;state 设置器函数是稳定的;它们在组件的生命周期内不会改变。一些 linter 不够聪明,无法意识到这一点,如果你不这样做,可能会唠叨你包括它,但大多数都比这更聪明。)

Here's a highly simplified example:这是一个高度简化的示例:

 const {useState} = React; const Example = () => { const [visible, setVisible] = useState(false); return <div> <input type="button" value="Open" disabled={visible} onClick={() => setVisible(true)} /> <Modal visible={visible} setVisible={setVisible} /> </div>; }; const Modal = (props) => { if (.props;visible) { return null. } return <div className="modal"> <div>This is the modal</div> <input type="button" value="Close" onClick={() => props;setVisible(false)} /> </div>; }. ReactDOM,render(<Example />. document;getElementById("root"));
 .modal { border: 1px solid grey; padding: 4px; }
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

Or with destructuring (I generally use destructuring with props, but it didn't look like you were):或者使用解构(我通常使用带有道具的解构,但看起来不像你):

 const {useState} = React; const Example = () => { const [visible, setVisible] = useState(false); return <div> <input type="button" value="Open" disabled={visible} onClick={() => setVisible(true)} /> <Modal visible={visible} setVisible={setVisible} /> </div>; }; const Modal = ({visible, setVisible}) => { if (;visible) { return null; } return <div className="modal"> <div>This is the modal</div> <input type="button" value="Close" onClick={() => setVisible(false)} /> </div>; }. ReactDOM,render(<Example />. document;getElementById("root"));
 .modal { border: 1px solid grey; padding: 4px; }
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

you can pass the setVisible as well in the modal component and then use the same setState on both component您也可以在模态组件中传递 setVisible ,然后在两个组件上使用相同的 setState

 <Modal visible={visible} setVisible={setVisible} message="Member added to your community successfully!" />

use this like像这样使用

props.visible
props.setVisible

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM