【发布时间】:2021-09-21 19:55:23
【问题描述】:
我正在实现两个相邻的文本字段,它们具有作为按钮的结尾装饰。这些按钮切换弹出器的可见性。每个popper都有clickawaylistener,所以当鼠标在popper外面点击时popper关闭。如果第一个弹出器打开,它应该在我单击第二个文本字段装饰的按钮时关闭。问题是结束装饰停止了事件传播。我这样做是为了防止在单击装饰时发生 clickaway 事件,从而防止在切换处理程序打开 popper 时立即关闭它。
我正在考虑将 TextField 包装到 ClickAwayListener 中,但没有成功。
附:两个 TextField 都将由单独的组件呈现,我不想在它们之间共享任何道具,因为它们应该是独立的。
https://codesandbox.io/s/basictextfields-material-demo-forked-rykrx
const [firstPopperVisible, setFirstPopperVisible] = React.useState(false);
const [secondPopperVisible, setSecondPopperVisible] = React.useState(false);
const firstTextFieldRef = React.useRef();
const secondTextFieldRef = React.useRef();
const toggleFirstPopperVisible = (e) => {
e.stopPropagation();
setFirstPopperVisible((prev) => !prev);
};
const handleFirstPopperClickAway = (e) => {
setFirstPopperVisible(false);
};
const toggleSecondPopperVisible = (e) => {
e.stopPropagation();
setSecondPopperVisible((prev) => !prev);
};
const handleSecondPoppertClickAway = (e) => {
setSecondPopperVisible(false);
};
return (
<div style={{ display: "flex", flexDirection: "row" }}>
<div>
<TextField
label="Outlined"
variant="outlined"
inputRef={firstTextFieldRef}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
edge="end"
onClick={toggleFirstPopperVisible}
>
<Visibility />
</IconButton>
</InputAdornment>
)
}}
/>
<ClickAwayListener onClickAway={handleFirstPopperClickAway}>
<Popper
open={firstPopperVisible}
anchorEl={firstTextFieldRef.current}
placement="bottom-start"
>
Content
</Popper>
</ClickAwayListener>
</div>
<div>
<TextField
label="Outlined"
variant="outlined"
inputRef={secondTextFieldRef}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
edge="end"
onClick={toggleSecondPopperVisible}
>
<Visibility />
</IconButton>
</InputAdornment>
)
}}
/>
<ClickAwayListener onClickAway={handleSecondPoppertClickAway}>
<Popper
open={secondPopperVisible}
anchorEl={secondTextFieldRef.current}
placement="bottom-start"
>
Content
</Popper>
</ClickAwayListener>
</div>
</div>
);
}
编辑:通过将 TextField 包装到 div 然后包装 tat ClickawayListener 找到了一个临时解决方案。还可以在需要时防止在 popper 本身上传播。这并不理想,但对我来说它有效。
<ClickAwayListener onClickAway={handleFirstPopperClickAway}>
<div style={{display: inline-box}>
<TextField>
.....
</TextField>
</div>
</ClickawayListener>
<Popper>
....
</Popper>
【问题讨论】:
-
您只是想切换输入内容的可见性——还是想在输入之外显示内容?
-
我想在输入下方显示自定义项目选择器,以便用户可以将信息写入输入以及从输入下方的列表(popper)中选择。
标签: reactjs material-ui