无法在 React Material-UI 中的 useState 中设置值
Posted
技术标签:
【中文标题】无法在 React Material-UI 中的 useState 中设置值【英文标题】:Not able to setValue in useState in React Material-UI 【发布时间】:2021-12-02 16:24:54 【问题描述】:我在 Material-UI 中创建了一个自定义对话框组件
const CustomDialog = (props) =>
const [dialogOpenState, setOpen] = React.useState(props.dilaogOpenProp);
return (
<>
<CssBaseline />
<Dialog
fullWidth
onClose=() =>
open=dialogOpenState
maxWidth="xs"
sx=
backdropFilter: "blur(5px)",
>
<DialogTitle>Example Dialog</DialogTitle>
<DialogContent>Example Content Here</DialogContent>
<DialogActions>
<Button>ooooh.</Button>
</DialogActions>
</Dialog>
<Box
sx=
minHeight: "100vh",
background:
"url(https://source.unsplash.com/random) no-repeat center center",
backgroundSize: "cover",
></Box>
</>
);
export default CustomDialog;
我正在尝试使用 useState
管理另一个组件的打开关闭
const Minidrawer = props =>
const theme = useTheme();
const history = props;
const [open, setOpen] = React.useState(false);
const [dialogOpen,setDialogueOpen] = React.useState(false)
const handleDialogueOpen = () =>
console.log("clicked");
setDialogueOpen(true)
return (
<Box sx= display: 'flex' >
<AppBar position="fixed" open=open>
<Toolbar>
<Typography variant="h6" noWrap component="div">
COMPANY NAME
</Typography>
<Button onClick=handleDialogueOpen>Filter</Button>
</Toolbar>
</AppBar>
<CustomDialog dilaogOpenProp=dialogOpen/>
</Box>
);
export default withRouter(Minidrawer);
我正在尝试使用 useState
将在对话框中传递的 dialogOpen
属性值设置为 false,我在控制台中被点击但 dilaog 没有被调用,如果我手动设置 dialogOpen
在 useState
它的工作但不是点击,这里发生了什么?
【问题讨论】:
dilaogOpenProp
变量中有错字。
【参考方案1】:
问题是您将道具复制到CustomDialog
中的状态。这意味着CustomDialog
会忽略父项中对dilaogOpenProp
的更改。 (这通常是 not best practice,但在某些极端情况下它可能有意义。)既然你这样做了,CustomDialog
只使用该道具的 initial 值,而不是更新后的值当您的父组件更改它时。下面是一个更简单的示例:
const useState = React;
const Child = (props) =>
const [childValue, setChildValue] = useState(props.parentValue);
return <div>
<div><code>props.parentValue = String(props.parentValue)</code></div>
<div><code>childValue = String(childValue)</code></div>
</div>;
;
const Parent = () =>
const [parentValue, setParentValue] = useState(false);
const toggleParentValue = () => setParentValue(v => !v);
return <div>
<Child parentValue=parentValue />
<div>
<button onClick=toggleParentValue>
Toggle <code>parentValue</code>
</button>
</div>
</div>;
;
ReactDOM.render(<Parent />, document.getElementById("root"));
<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>
您需要要么将打开/关闭状态存储在父级中并让父级控制它,或将打开/关闭状态存储在CustomDialog
中并拥有CustomDialog
控制它。你不能两者都做。
这通常意味着让父母控制,但将一个函数传递给孩子,孩子可以使用该函数告诉父母发生了变化。例如,如果您需要 CustomDialog
能够自行关闭(在对话框中很常见),您可以将其传递给父级提供的执行此操作的函数。
【讨论】:
【参考方案2】:如果您希望子组件的状态根据父组件提供的道具更新,您可以使用useEffect
。您将 prop 传递给子组件 (React.useState(props.dilaogOpenProp)
) 中的 useState
,这仅在第一次渲染中有效:
const [dialogOpenState, setOpen] = React.useState(props.dilaogOpenProp);
useEffect(() =>
// update the state every time the prop.dilaogOpenProp dependency changes
setOpen(props.dilaogOpenProp);
, [props.dilaogOpenProp]);
【讨论】:
【参考方案3】:你必须保持状态更新,使用useState
:
const CustomDialog = ( dilaogOpenProp ) =>
const [dialogOpenState, setOpen] = React.useState(dilaogOpenProp);
useEffect(() =>
setOpen(props.dialogOpenState);
, [dilaogOpenProp])
);
你也可以直接从props中获取值
<Dialog open=props.dilaogOpenProp>
...
</Dialog>
【讨论】:
以上是关于无法在 React Material-UI 中的 useState 中设置值的主要内容,如果未能解决你的问题,请参考以下文章
如何使 Material-UI Dialog 在 React 中工作
TS 表达式生成的联合类型过于复杂,无法用 Material-UI 和 @react-three/fiber 表示
在 Material-ui 中使用 mixins 自定义 React 中的组件