如何在反应中的组件之间传递useState?
How to pass useState amoung the components in react?
我有一个注册页面和模态组件。在寄存器中有一个 useState
用于模态的可见性。我将它作为道具传递给 Modal。当模式关闭时如何更改注册页面中的 useState
值。
注册页面:
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
模态组件:
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)
您应该只有 一个 visible
状态成员,在父组件或子组件 (Modal
) 中,而不是在两个地方。
如果你把它放在父级中,你可以像任何其他道具一样将它传递给子级:
return <Modal visible={visible} setVisible={setVisible}>{/*...*/}</Modal>
Modal
的代码然后可以使用适当的标志调用 props.setVisible
。
如果您 仅 希望 Modal
能够隐藏自己(而不是显示自己),您可以传递一个调用 setVisible(false)
的包装函数:
const hide = useCallback(() => setVisible(false), [setVisible]);
// Optional, see below −−−−−−−−−−−−−^^^^^^^^^^
// ...
return <Modal visible={visible} hide={hide}>{/*...*/}</Modal>
...然后 Modal
的代码调用 hide()
来隐藏模式。
(使 setVisible
成为 useCallback
调用中的依赖项是可选的;状态 setter 函数是 稳定的 ;它们在组件的生命周期内不会改变。一些 linters 不够聪明,无法意识到这一点,如果你不包含它可能会唠叨你,但大多数都比那更聪明。)
这是一个高度简化的示例:
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>
或者使用解构(我通常将解构与 props 一起使用,但它看起来不像你那样):
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>
您也可以在模态组件中传递 setVisible,然后在两个组件上使用相同的 setState
<Modal visible={visible} setVisible={setVisible} message="Member added to your community successfully!" />
像这样使用
props.visible
props.setVisible
我有一个注册页面和模态组件。在寄存器中有一个 useState
用于模态的可见性。我将它作为道具传递给 Modal。当模式关闭时如何更改注册页面中的 useState
值。
注册页面:
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
模态组件:
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)
您应该只有 一个 visible
状态成员,在父组件或子组件 (Modal
) 中,而不是在两个地方。
如果你把它放在父级中,你可以像任何其他道具一样将它传递给子级:
return <Modal visible={visible} setVisible={setVisible}>{/*...*/}</Modal>
Modal
的代码然后可以使用适当的标志调用 props.setVisible
。
如果您 仅 希望 Modal
能够隐藏自己(而不是显示自己),您可以传递一个调用 setVisible(false)
的包装函数:
const hide = useCallback(() => setVisible(false), [setVisible]);
// Optional, see below −−−−−−−−−−−−−^^^^^^^^^^
// ...
return <Modal visible={visible} hide={hide}>{/*...*/}</Modal>
...然后 Modal
的代码调用 hide()
来隐藏模式。
(使 setVisible
成为 useCallback
调用中的依赖项是可选的;状态 setter 函数是 稳定的 ;它们在组件的生命周期内不会改变。一些 linters 不够聪明,无法意识到这一点,如果你不包含它可能会唠叨你,但大多数都比那更聪明。)
这是一个高度简化的示例:
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>
或者使用解构(我通常将解构与 props 一起使用,但它看起来不像你那样):
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>
您也可以在模态组件中传递 setVisible,然后在两个组件上使用相同的 setState
<Modal visible={visible} setVisible={setVisible} message="Member added to your community successfully!" />
像这样使用
props.visible
props.setVisible