Wrapping/facading 一个 ScalaJS 以尽可能封装的方式反应 js 组件(react-sticky)
Wrapping/facading a ScalaJS react js component (react-sticky) in the most encapsulating manner possible
我见过几种在 scala.js
中制作立面或包装 Javascript 组件的方法,包括为 react.js Component
这样做。他们似乎在封装或隐藏组件本身提供的功能的程度上有所不同,我想是根据他们的需要(也许他们只需要调用一种方法)。
在我的例子中,我需要使用一个名为 react-sticky
的组件,我首先尝试确定如何继续为其仅有的两个组件之一制作外观 classes,StickyContainer
, code provided here.
我的问题如下:
- 如何处理
scala
中的 static
Javascript 方法?我什至需要关心这个,还是我可以对此不可知?
- 我需要做的 最小 量是多少 "facade" 我只需要在另一个 [= 中包含
component
而没有任何 Props
19=] 的 render()
?
- 与任何其他
js
原生 class 组件相比, 包装或外观 reactjs
组件在根本上有什么不同?
最后,以下哪种策略最合适?
@js.native
trait StickyContainer extends js.Object { ... }
object StickyContainer extends StickyContainer {}
或
case class StickyContainer(offset: js.UndefOr[Double],...) {
def apply() = { React.createElement(ReactUniversal.Image, JSMacro[StickyContainer](this), children: _*)
}
How do I deal with static Javascript methods in scala? Do I even need to care about this, or can I be agnostic about it?
当你想包装它时,你不需要担心反应组件的底层实现。但一般来说,如果你想为 class
指定静态字段
@ScalaJSDefined
class MyComponent extends ReactComponent {
...
}
val ctor = js.constructorOf[MyComponent]
ctor.childContextTypes = js.Dictionary("contextfield" -> React.PropTypes.`object`.isRequired)
如果您想了解 scala.js 中开箱即用的静态字段支持...... https://github.com/scala-js/scala-js/issues/1902
What is the minimum amount of "facade" I need to make to just include the component without any Props in another component's render()?
global.ReactSticky = require('react-sticky') // load js lib
@js.native
object ReactSticky extends js.Object {
val StickyContainer : js.Dynamic = js.native
val Sticky : js.Dynamic = js.native
}
//Using JSMacro
case class StickyContainer(fields ..) {
def apply(children : ReactNode*) = {
val props = JSMacro[StickyContainer](this)
React.createElement(ReactSticky.StickyContainer,props,children :_*)
}
}
//Using FunctionMacro
def StickyContainer(fields ..)(children : ReactNode*) : ReactElement = {
val props = FunctionMacro()
React.createElement(ReactSticky.StickyContainer,props,children :_*)
}
}
What is fundamentally different about wrapping or facading a reactjs component as opposed to any other js native class?
如果看到object ReactSticky extends js.Object ...
写门面没有区别。但在 React 世界中,你需要 ReactElement
这就是你需要额外包装器的地方 - React.createElement(classCtor,props,children)
调用 ..
向 invariant
提供关于如何使 SRI-based 组件正常工作的正确答案。其他基于 japgolly
的在处理 third-party JS 时并不友好。
以下是我如何获得库 react-mt-svg-lines
,一个动画库,正在运行:
克拉兹
case class MtSvgLines(
key: js.UndefOr[String] = js.undefined,
ref: js.UndefOr[String] = js.undefined,
animate: js.Any = true,
duration: Double = 10.0,
stagger: js.UndefOr[Double] = js.undefined,
timing: js.UndefOr[String] = js.undefined,
playback: js.UndefOr[String] = js.undefined,
fade: js.UndefOr[String] = js.undefined
)
{
def apply(children: ReactNode*): ReactComponentU_ = {
val props = JSMacro[MtSvgLines](this)
val f = React.asInstanceOf[js.Dynamic].createFactory(js.Dynamic.global.SvgLines.default)
if (children.isEmpty)
f(props).asInstanceOf[ReactComponentU_]
else if (children.size == 1)
f(props, children.head).asInstanceOf[ReactComponentU_]
else
f(props, children.toJsArray).asInstanceOf[ReactComponentU_]
}
}
值得注意的是,确保 createFactory
中的参数是您 export
的 global.Whatever
。考虑 children 的数字差异。对每个可选项使用 js.UndefOr
。
客户
def render(S: State, C: PropsChildren) = {
<.header(^.key := UUID.randomUUID().toString, Styles.Header_TextIsCentered, Styles.Header_BackgroundIsGrayBlue_WithWhiteText)(
<.div(^.className := "container")(
<.h1()("justin shin, tampa fl"),
MtSvgLines(animate = true, duration = 500) {
import japgolly.scalajs.react.vdom.svg.all._
svg(SvgStyles.svg,
defs(
maskTag(id := "mask", x := "0", y := "0", width := "100%", height := "100%",
rect(id := "alpha", x := "0", y := "0", width := "100%", height := "100%"),
text(id := "title", x := "50%",y := "0", dy := "1.58em")("Justin", transform := "translate(50, 0)"),
text(id := "title", x := "50%",y := "0", dy := "1.58em")("Tampa")
)
),
rect(id := "base", x := "0", y := "0", width := "100%", height := "100%"),
path(stroke := "green", strokeWidth := "10", fill := "none", d := "M20.8,51c0,0,20.8,18.2,21.5,18.2c0.6,0,33.3-38.5,33.3-38.5"),
)
}
)
)
}
我见过几种在 scala.js
中制作立面或包装 Javascript 组件的方法,包括为 react.js Component
这样做。他们似乎在封装或隐藏组件本身提供的功能的程度上有所不同,我想是根据他们的需要(也许他们只需要调用一种方法)。
在我的例子中,我需要使用一个名为 react-sticky
的组件,我首先尝试确定如何继续为其仅有的两个组件之一制作外观 classes,StickyContainer
, code provided here.
我的问题如下:
- 如何处理
scala
中的static
Javascript 方法?我什至需要关心这个,还是我可以对此不可知? - 我需要做的 最小 量是多少 "facade" 我只需要在另一个 [= 中包含
component
而没有任何Props
19=] 的render()
? - 与任何其他
js
原生 class 组件相比, 包装或外观reactjs
组件在根本上有什么不同?
最后,以下哪种策略最合适?
@js.native
trait StickyContainer extends js.Object { ... }
object StickyContainer extends StickyContainer {}
或
case class StickyContainer(offset: js.UndefOr[Double],...) {
def apply() = { React.createElement(ReactUniversal.Image, JSMacro[StickyContainer](this), children: _*)
}
How do I deal with static Javascript methods in scala? Do I even need to care about this, or can I be agnostic about it?
当你想包装它时,你不需要担心反应组件的底层实现。但一般来说,如果你想为 class
指定静态字段 @ScalaJSDefined
class MyComponent extends ReactComponent {
...
}
val ctor = js.constructorOf[MyComponent]
ctor.childContextTypes = js.Dictionary("contextfield" -> React.PropTypes.`object`.isRequired)
如果您想了解 scala.js 中开箱即用的静态字段支持...... https://github.com/scala-js/scala-js/issues/1902
What is the minimum amount of "facade" I need to make to just include the component without any Props in another component's render()?
global.ReactSticky = require('react-sticky') // load js lib
@js.native
object ReactSticky extends js.Object {
val StickyContainer : js.Dynamic = js.native
val Sticky : js.Dynamic = js.native
}
//Using JSMacro
case class StickyContainer(fields ..) {
def apply(children : ReactNode*) = {
val props = JSMacro[StickyContainer](this)
React.createElement(ReactSticky.StickyContainer,props,children :_*)
}
}
//Using FunctionMacro
def StickyContainer(fields ..)(children : ReactNode*) : ReactElement = {
val props = FunctionMacro()
React.createElement(ReactSticky.StickyContainer,props,children :_*)
}
}
What is fundamentally different about wrapping or facading a reactjs component as opposed to any other js native class?
如果看到object ReactSticky extends js.Object ...
写门面没有区别。但在 React 世界中,你需要 ReactElement
这就是你需要额外包装器的地方 - React.createElement(classCtor,props,children)
调用 ..
向 invariant
提供关于如何使 SRI-based 组件正常工作的正确答案。其他基于 japgolly
的在处理 third-party JS 时并不友好。
以下是我如何获得库 react-mt-svg-lines
,一个动画库,正在运行:
克拉兹
case class MtSvgLines(
key: js.UndefOr[String] = js.undefined,
ref: js.UndefOr[String] = js.undefined,
animate: js.Any = true,
duration: Double = 10.0,
stagger: js.UndefOr[Double] = js.undefined,
timing: js.UndefOr[String] = js.undefined,
playback: js.UndefOr[String] = js.undefined,
fade: js.UndefOr[String] = js.undefined
)
{
def apply(children: ReactNode*): ReactComponentU_ = {
val props = JSMacro[MtSvgLines](this)
val f = React.asInstanceOf[js.Dynamic].createFactory(js.Dynamic.global.SvgLines.default)
if (children.isEmpty)
f(props).asInstanceOf[ReactComponentU_]
else if (children.size == 1)
f(props, children.head).asInstanceOf[ReactComponentU_]
else
f(props, children.toJsArray).asInstanceOf[ReactComponentU_]
}
}
值得注意的是,确保 createFactory
中的参数是您 export
的 global.Whatever
。考虑 children 的数字差异。对每个可选项使用 js.UndefOr
。
客户
def render(S: State, C: PropsChildren) = {
<.header(^.key := UUID.randomUUID().toString, Styles.Header_TextIsCentered, Styles.Header_BackgroundIsGrayBlue_WithWhiteText)(
<.div(^.className := "container")(
<.h1()("justin shin, tampa fl"),
MtSvgLines(animate = true, duration = 500) {
import japgolly.scalajs.react.vdom.svg.all._
svg(SvgStyles.svg,
defs(
maskTag(id := "mask", x := "0", y := "0", width := "100%", height := "100%",
rect(id := "alpha", x := "0", y := "0", width := "100%", height := "100%"),
text(id := "title", x := "50%",y := "0", dy := "1.58em")("Justin", transform := "translate(50, 0)"),
text(id := "title", x := "50%",y := "0", dy := "1.58em")("Tampa")
)
),
rect(id := "base", x := "0", y := "0", width := "100%", height := "100%"),
path(stroke := "green", strokeWidth := "10", fill := "none", d := "M20.8,51c0,0,20.8,18.2,21.5,18.2c0.6,0,33.3-38.5,33.3-38.5"),
)
}
)
)
}