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

时间:2016-04-26 22:02:03

标签: javascript reactjs porting scala.js

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

  • container,初始化并将context传递给child ...
  • sticky,它使用context和滚动位置来实现粘性标题效果。

我花费了大约两个小时或更长的时间将这个费力地移植到ReactJS scalajs中,我粘贴到目前为止所做的工作之下。它不编译;还有松散的电线。

我开始认为我应该放弃,因为也许我的道路不是很好。我尝试做的是取消context库中sjs使用ParentProps的{​​{1}},并将其状态传递给孩子并返回。

然而,考虑到所涉及的活动部件的数量,我不相信这甚至可能有效。我需要知道是否有更好的方法来移植。

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

}

1 个答案:

答案 0 :(得分:0)

所以真的有两个答案:第一个答案是,我仍然不知道如何在context wrt scalajs内使用reactjs,但第二个答案是,这并不重要,而且从那时起我就像其他十个小react个lib一样没有问题。我专注于移植我不需要移植的方法。

您只需按照https://github.com/chandu0101/scalajs-react-components/blob/master/doc/InteropWithThirdParty.md上的指南操作即可。如果你已经搜索了一段时间,你可能已经看到了这个并且可能没有相信它会起作用(我没有完全理解它会起作用),因为你所做的只是复制Props并创建一个虚构造函数。嗯,这就是你需要做的一切 - 很有可能 - 所以在处理这个任务之前,尝试只移植那个页面上需要的内容。