我使用scalajs 0.6.15与scalajs-react 0.11.3和reactjs 15.4.2。
考虑一个组件SomeComp
,其中Props
的值的类型需要参数化。
由于在使用组件构建器时需要知道类型,因此我将组件包装在类中。
class SomeComp[T]() {
case class Props(t: T, onChange: T => Callback)
val component = ReactComponentB[Props]("SomeComp")...
def apply(t: T, onChange:T => Callback) = component(Props(t, onChange))
}
这是有效的。问题是,除非SomeComp
的用户首先创建SomeComp
的实例并在父{q}}方法中使用此实例,否则每次重新呈现父组件都会重新装入组件。 / p>
我的黑客解决方案是避免这种情况:
render
有更好的,更少的锅炉代码,不那么糟糕的方式吗?有什么建议吗?
更新 在@ Golly之后(感谢您精心解答!)建议我发现第二个解决方案最优雅,并希望在此处发布完整性:
object SomeComp {
val genericComp = SomeComp[Any]()
def apply[T](t: T, onChange: T => Callback) = genericComp(
t = t,
onChange = (a: Any) => onChange(a.asInstanceOf[T])
)
}
答案 0 :(得分:1)
1a)围绕建造者的类。正是你在第一个例子中所拥有的除了之外的一个重要区别:每个类型只创建一个类。为同一类型创建一个新类导致你看到的卸载/重新安装(因为React认为组件是不同的),就好像你这样做:
final class SomeComp[A] private[SomeComp] () {
val component = ReactComponentB[Props]("SomeComp")...
}
object SomeComp {
val Int = new SomeComp[Int]
val String = new SomeComp[String]
}
如果您事先不知道类型,那也很好,只需为您的类型创建一次类,并将其放在被调用者的伴随对象中。每种类型都需要创建一个单例,但所有内容仍然很简单。
1b)与上面类似,除了使用函数而不是类。每个类型创建一次(每个被调用者可选)并重用。
2)我不推荐这个,但你可以使用存在类型而不是通用类型,特别是使类型参数成为类型成员。
class Props {
type T
val value: T
val onChange: T => Callback
}
现在组件是单态的,但是你需要一些样板来很好地创建和使用Props类。
顺便说一句,如果您自己创建了一个(T x T→回调),那么您可以使用内置的一个:https://github.com/japgolly/scalajs-react/blob/master/doc/EXTRA.md#statesnapshot(doc for 1.0.0- RC1 +,曾经是两个类:{可重用,外部}在1.0天之前的变量}