是否有明确的途径可以实现在 ScalaJS + React 中广泛使用上下文的 React 组件?

Is there a clear path by which I could implement a React Component that uses context extensively in ScalaJS + React?

This component from react-sticky is one of two in the library.

我刚刚花了大约两个小时或更多时间将它费力地移植到 scalajs 中的 ReactJS 中,并且我已将到目前为止所做的粘贴在下面。它不编译;仍然有松动的电线。

我开始认为我应该放弃,因为也许我的道路不是一条好路。我试图做的是用 ParentProps 消除 sjs 库中不可用的 context 的使用,并将其状态传递给 child 并返回。

然而,考虑到涉及的移动部件数量,我对这甚至可能奏效失去了信心。我想知道是否有更好的移植方法。

package shindig.frontend.component.layout

import fr.iscpif.scaladget.mapping.ace.PlaceHolder
import japgolly.scalajs.react._
import japgolly.scalajs.react.vdom._
import japgolly.scalajs.react.vdom.prefix_<^._
import org.scalajs.dom.html.Div
import org.scalajs.dom.window
import org.scalajs.dom.raw.ClientRect

import scalacss.Defaults._

object StickyComponent {


  case class Props(
                    isActive: Boolean                   = true,
                    className: String                   = "",
                    style: Seq[StyleA]                  = Seq(),
                    stickyClassName: String             = "",
                    stickyStyle: Seq[StyleA]            = Seq(),
                    offsetTop:   Double                    = 0,
                    offsetBottom: Double                   = 0,
                    stickyStateChange: () ⇒ Callback    = () ⇒ (),
                    contextProps: StickyContainer.Props = StickyContainer.Props()
                  )

  case class State(isSticky: Boolean = false, origin: PlaceHolder)

  class Backend($:           BackendScope[Props, State]) {

    def componentDidMount(): Unit = {

    }

    def getNode: TopNode = ReactDOM.findDOMNode($)
    def getRect          = getNode.getBoundingClientRect()
    def getY             = window.pageYOffset

    def getOrigin(y: Double): Double = getPlaceholderRef.top + y
    def getPlaceholderRef = $.refs.apply[Div]("placeholder").get.getDOMNode().getBoundingClientRect()
    def getProps: Props  = $.props.runNow()

    def isBelow(y: Double, contextProps: StickyContainer.Props): Boolean =
      y + contextProps.offset >= getOrigin(y)

    def isAbove(y: Double, contextProps: StickyContainer.Props, offset: Double): Boolean =
      contextProps.offset <= contextProps.bottomOfRectOrNil - offset

    def isStickyAt(y: Double, origin: Double): Boolean = {
      val props = getProps
      val y = getY
      props.isActive && isBelow(y, props.contextProps) && isAbove(y, props.contextProps, props.offsetBottom)
    }

    def update() = $.setState(State(

    ))

  }

}

object StickyContainer {

  case class Props(
                    node: Option[TopNode] = None,
                    offset: Double = 0,
                    rect: Option[ClientRect] = None
                  ) {
    def bottomOfRectOrNil: Double = rect match {
      case Some(r) ⇒ r.bottom
      case None ⇒ 0
    }
  }

  case class State(
                    node: Option[TopNode] = None,
                    offset: Double = 0,
                    rect: Option[_] = None
                  ) {
    def withNode(node: TopNode) =
      State(Some(node), offset, rect)
  }

  class Backend($: BackendScope[Unit, State]) {

    def componentDidMount(): Unit = {
      $.modState(_.withNode(ReactDOM.findDOMNode($)))
    }

    def render() = {
      <.div(
        $.propsChildren()
      )
    }

  }

  val component =

    ReactComponentB[Unit]("StickyContainer")
      .initialState(State())
      .backend[Backend]($ ⇒ new Backend($))
      .renderBackend
      .build

}

所以实际上有两个答案:第一个答案是,我仍然不知道您如何在 scalajsreactjs 中使用 context,但第二个答案是,没关系,自从这次以来,我已经毫无问题地移植了其他十个 react 库。我专注于不需要移植的移植方法。

您只需按照 https://github.com/chandu0101/scalajs-react-components/blob/master/doc/InteropWithThirdParty.md 中的指南进行操作即可。如果您已经搜索了一段时间,您可能已经看到了这个并且可能不相信它会起作用(一开始我不太明白它会起作用),因为您所做的只是复制 Props并创建一个人造构造函数。好吧,这就是您需要做的全部 - 很可能 - 所以在处理此任务之前尝试仅移植该页面上需要的内容。