[英]How to not change the state at the first render of React component?
我正在尝试使用 React 创建一个 MUI 对话框组件并从包装组件管理它。 这是我的例子:
import { Dialog, DialogActions, DialogTitle, DialogContent, Button } from "@material-ui/core";
import React, {useState, useEffect} from "react";
export default function MultiNote(props) {
const [useDialogOpen, setDialogOpen] = useState(false);
useEffect(() => {
setDialogOpen(!useDialogOpen);
}, [props.open]);
const handleDialogToggle = () => {
setDialogOpen(!useDialogOpen);
}
return (
<Dialog
open={useDialogOpen}
onClose={handleDialogToggle}
aria-labelledby="form-multinote-dialog"
>
<DialogTitle id="form-multinote-dialog">{props.title}</DialogTitle>
<DialogContent>Test</DialogContent>
<DialogActions>
<Button onClick={handleDialogToggle} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
);
}
在这里,我正在尝试根据组件的 prop 的打开状态更改 useDialogOpen 状态。 除了第一次渲染外,它工作得很好。 在第一次渲染时,它会打开对话框。 但我希望它被关闭。
我不明白为什么它会改变。
我使用沙箱来测试您的代码。 您的 useEffect 正在将 useDialogOpen 切换为 true。
我在你的 useEffect 中使用了一个 if 语句来让它不显示对话框:
useEffect(() => {
if (Object.keys(props).length !== 0) {
setDialogOpen(!useDialogOpen);
}
}, [props.open]);
这是有效的,因为它确认了一个 prop 实际上正在被传递到组件中,而不仅仅是一个空对象。
这是一个包含所有代码的沙箱供您使用:
https://codesandbox.io/s/stoic-shaw-3dszx?file=/src/App.js:259-279
发生这种情况的原因是因为您正在观察 props.open 的更改,因为它总是在渲染阶段传入。 然后将您的 useDialog 切换为 true 并显示对话框。
回答你的第一个问题 - 为什么对话框在第一次渲染时打开? 发生的事情是这样的:
useDialogOpen
为 false(因为它是用useState(false)
创建的),并且对话框已关闭)。useEffect
运行,并调用setDialogOpen(!useDialogOpen)
。 由于useDialogOpen
当前为 false,这与setDialogOpen(true)
相同useDialogOpen
为 true 重新呈现。 如果您希望对话框打开状态由open
属性控制,您可能需要考虑提升 state 。 例如,摆脱这个组件内的所有状态,并向道具添加一个 onClose 事件。 所以它看起来像这样:
function MultiNote(props) {
return (
<Dialog
open={props.open}
onClose={props.onClose}
aria-labelledby="form-multinote-dialog"
>
<DialogTitle id="form-multinote-dialog">{props.title}</DialogTitle>
<DialogContent>Test</DialogContent>
<DialogActions>
<Button onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</Dialog>
);
}
它可以像这样使用:
function App() {
const [isOpen, setIsOpen] = useState(false);
return <MultiNote open={isOpen} onClose={() => setIsOpen(false)} />;
}
看到这个代码和框
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.