3

首先让我说我理解你永远不应该使用 refs。

话虽如此,我认为在我的情况下这是非常有效的。具体来说,我使用的是 window.onscroll 处理程序,不能简单地更改 onscroll 处理程序中的道具。在 onscroll 处理程序中更改状态或道具会过于频繁地重新呈现子组件,这会导致过多的延迟。

因此,由于我的场景只需要在滚动时设置元素的样式(即,当页面滚动到视图之外时,我会在页面顶部粘贴一些东西),因此只需设置即可获得 0 延迟this.refs.myelement.style.position = 'fixed'

我的问题是我目前正在做:

this.refs.childelement.refs.childschildelement.refs.childschildschildselement.refs.style.position = 'fixed'

基本上,我的onscroll handler3 位父母都对我想要设计的实际元素提出了意见。

我的页面由一个List组件组成。这由ReadOnlyOrEditable组件组成。可编辑组件是RichTextEditors具有组件的Toolbar组件。当窗口滚动事件发生时Toolbar ,我需要将位置设置为固定。

因此,在一个页面上,我将有大约 10 个ReadOnlyOrEditable组件,其中可能有 5 个是RichTextEditors,每个组件都有一个Toolbar.

工具栏有斜体、粗体等按钮。

当用户向下滚动时,如果工具栏消失,我们不希望用户必须向上滚动。也就是说,如果工具栏不在视野范围内,我们希望将位置设置为固定,以便用户可以立即点击斜体/粗体/等。

那么如何在不必自上而下传递 refs 的情况下让它变得更好呢?我现在拥有它的方式非常丑陋......

我更喜欢让 onscroll 处理程序靠近列表的位置,因为在每个 Toolbar 组件中都有 window.onscroll 处理程序意味着我正在设置多个 window.scroll 处理程序,这在浏览器上是不必要的工作。

欢迎任何建议。

4

2 回答 2

0

像所有事情一样,我相信有很多方法可以解决一个问题,这就是我将如何解决它。

  1. 我会将注册/注销到节点滚动事件和在预定位置触发自定义事件的责任抽象到“服务”。
  2. 可滚动组件或应用程序容器(List组件?)将成为滚动通知服务与其子项之间的粘合剂
  3. 可滚动组件将通过 props 将自定义注册函数传递给其子组件。此自定义注册函数将接收节点(工具栏)以监视位置和回调以设置/取消设置固定位置
  4. 孩子(组件)将使用节点 from和回调RichTextEditor调用函数(例如onRegisterPinableToolbar),孩子可以使用该回调来修改其节点样式。componentDidMountReactDOM.findDOMNode

笔记:

  • 当然,您还需要清理componentWillUnmount.
  • 不太了解您的应用程序,但我会尝试为编辑器创建一个 HOC,例如PinableToolbarRichTextEditor
  • 通过将注册滚动事件抽象为服务,您可以使用 requestAnimationFrame 进行优化,并为旧浏览器提供回退。
  • 传递给孩子的函数看起来像这样(node:Node, setPinability:Function) => unregister:Function

我知道命名pinability不是最好的

于 2016-11-08T01:35:52.937 回答
0

与其尝试获取深度嵌套组件的引用,不如将“固定”状态作为道具传递,并让伟大的(伟大的?)孙子检查属性并设置自己的样式。

于 2016-11-09T20:23:14.930 回答