React:HTML 详细信息在开始打开时无法控制地切换
Posted
技术标签:
【中文标题】React:HTML 详细信息在开始打开时无法控制地切换【英文标题】:React: HTML Details toggles uncontrollably when starts open 【发布时间】:2020-03-15 11:27:48 【问题描述】:我正在尝试使用 html <details>
标记来创建一个简单的可扩展部分,该部分使用语义 html 与 React 相结合。
<details><summary></summary></details>
行为开箱即用效果很好,对于使用 IE 的 1-2% 的用户来说,这些用户没有了解内容的显示隐藏特性,这真的不是结束暂时始终显示内容的世界。
我的问题出现在使用 React 挂钩来保持 <details>
面板是打开还是关闭时。 React 组件的基本布局如下:
const DetailsComponent = (startOpen) =>
const [open, toggleOpen] = useState(startOpen);
return (
<details onToggle=() => toggleOpen(!open) open=open>
<summary>Summary</summary>
<p>Hidden content hidden content hidden content</p>
</details>
);
;
我需要使用onToggle
事件的原因是更新open
状态变量以在我的真实示例中触发其他一些javascript。我使用startOpen
属性来决定是否在页面上呈现详细信息窗格是打开还是关闭。
当我将组件用作<DetailsComponent startOpen= false />
时,会发生预期的行为。
但是,当我想在加载时打开窗格 (<DetailsComponent startOpen= true />
) 开始时,我可以看到窗格打开和关闭的速度非常非常快,并且永远一遍又一遍。
【问题讨论】:
【参考方案1】:我认为你应该使用 prevState
<details onToggle=() => toggleOpen(prevOpen => !prevOpen ) open=open>
【讨论】:
谢谢你,不幸的是,这对我不起作用,但我认为通常更好的做法是在切换打开中明确使用以前的状态,因为它更明确地使用 Hooks。 【参考方案2】:<details>
HTML 元素不需要用js控制,因为它已经具备了打开和关闭的功能。当您传递open
属性并在ontoggle
事件中更改它时,您将创建一个无限的事件循环,因为元素被切换,然后打开状态更改,从而触发触发ontoggle
事件的元素等等。 .. 您唯一需要做的就是传递初始打开状态。
const DetailsComponent = (startOpen) =>
return (
<details open=startOpen>
<summary>Summary</summary>
<p>Hidden content hidden content hidden content</p>
</details>
);
;
【讨论】:
感谢您的回答,不幸的是,我声明我需要一种方法来跟踪组件内其他逻辑的详细打开/关闭状态。但你是对的,details 组件开箱即用,效果很好! 这解决了我的问题,谢谢:)【参考方案3】:似乎onToggle
在挂载之前被调用,这会导致它在打开的情况下出现无限循环。因为这会触发一个新的切换事件。
避免这种情况的一种方法是检查details
标签是否已安装,并且仅在安装后才切换。这样你就忽略了第一个切换事件。
const DetailsComponent = ( startOpen ) =>
const [open, toggleOpen] = useState(startOpen);
const [isMounted, setMount] = useState(false);
useEffect(() =>
setMount(true);
, []);
return (
<details onToggle=() => isMounted && toggleOpen(!open) open=open>
<summary>Summary</summary>
<p>Hidden content hidden content hidden content</p>
</details>
);
;
您可以在 Codesandbox 中找到工作演示。
【讨论】:
这对我来说是一个很好的解决方案,不确定它是否对元素来说太过分了,但这肯定会在代码审查中出现!【参考方案4】:我遇到了同样的问题。我最终发现我可以通过处理onToggle
来监控当前状态,而不是使用它来设置open
属性。
export default ( defaultOpen, summary, children : DetailsProps): JSX.Element =>
const [expanded, setExpanded] = useState(defaultOpen || false);
return (
<details open=defaultOpen onToggle=e => setExpanded((e.currentTarget as HTMLDetailsElement).open)>
<summary>
expanded ? <ExpandedIcon /> : <CollapsedIcon />
summary
</summary>
children
</details>
);
;
因为defaultOpen
不改变它不会导致DOM更新,所以HTML控件仍然负责它的状态。
【讨论】:
以上是关于React:HTML 详细信息在开始打开时无法控制地切换的主要内容,如果未能解决你的问题,请参考以下文章
键盘打开时TextInput不可见Expo React Native
React Native, IOS Simulator 打开模拟器时出错。查看地铁日志以获取详细信息
从 Documents 目录在 UIWebview 中打开时,ios-css 和 js 无法在 html 文件中链接