Skip to content

Commit

Permalink
Fix setState crash when a component defines the state type as a Seq
Browse files Browse the repository at this point in the history
  • Loading branch information
shadaj committed Oct 9, 2019
1 parent aa93a74 commit c899120
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 20 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Changelog

## vNEXT
### Highlights :tada:
+ Improve experience using `ReactElement`s within first-order types such as Map and List [PR #285](https://github.com/shadaj/slinky/pull/285)
+ Support [React Native's Keyboard API](https://facebook.github.io/react-native/docs/keyboard) [PR #293](https://github.com/shadaj/slinky/pull/293)

### Bug Fixes
+ Fix crashes when calling `setState` on a component with `Props` set to some subtype of `Function1` [PR #295](https://github.com/shadaj/slinky/pull/295)
+ Support `useCallback` with a function that takes arguments [PR #290](https://github.com/shadaj/slinky/pull/290)
+ Fix issues around using ReactElements within first-order types e.g. Map, List [PR #285](https://github.com/shadaj/slinky/pull/285)
+ Support [React Native's Keyboard API](https://facebook.github.io/react-native/docs/keyboard) via a scalajs facade [PR #293](https://github.com/shadaj/slinky/pull/293)

## [v0.6.2](https://slinky.dev)
### Highlights :tada:
Expand Down
13 changes: 6 additions & 7 deletions core/src/main/scala/slinky/core/DefinitionBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ abstract class DefinitionBase[Props, State, Snapshot](jsProps: js.Object) extend
readStateValue(this.asInstanceOf[PrivateComponentClass].stateR)
}

@JSName("setState_scala")
@JSName("setState_scala_1")
@inline final def setState(s: State): Unit = {
val stateObject = if (BaseComponentWrapper.scalaComponentWritingEnabled) {
writeWithWrappingAdjustment(stateWriter)(s)
Expand All @@ -66,7 +66,7 @@ abstract class DefinitionBase[Props, State, Snapshot](jsProps: js.Object) extend
this.asInstanceOf[PrivateComponentClass].setStateR(stateObject)
}

@JSName("setState_scala")
@JSName("setState_scala_2")
@inline final def setState(fn: State => State): Unit = {
this.asInstanceOf[PrivateComponentClass].setStateR((ps: js.Object) => {
val s = fn(readStateValue(ps))
Expand All @@ -76,7 +76,7 @@ abstract class DefinitionBase[Props, State, Snapshot](jsProps: js.Object) extend
})
}

@JSName("setState_scala")
@JSName("setState_scala_3")
@inline final def setState(fn: (State, Props) => State): Unit = {
this.asInstanceOf[PrivateComponentClass].setStateR((ps: js.Object, p: js.Object) => {
val s = fn(readStateValue(ps), readPropsValue(p))
Expand All @@ -86,15 +86,15 @@ abstract class DefinitionBase[Props, State, Snapshot](jsProps: js.Object) extend
})
}

@JSName("setState_scala")
@JSName("setState_scala_4")
@inline final def setState(s: State, callback: () => Unit): Unit = {
val stateObject = if (BaseComponentWrapper.scalaComponentWritingEnabled) {
writeWithWrappingAdjustment(stateWriter)(s)
} else js.Dynamic.literal(__ = s.asInstanceOf[js.Any])
this.asInstanceOf[PrivateComponentClass].setStateR(stateObject, callback)
}

@JSName("setState_scala")
@JSName("setState_scala_5")
@inline final def setState(fn: State => State, callback: () => Unit): Unit = {
this.asInstanceOf[PrivateComponentClass].setStateR((ps: js.Object) => {
val s = fn(readStateValue(ps))
Expand All @@ -104,7 +104,7 @@ abstract class DefinitionBase[Props, State, Snapshot](jsProps: js.Object) extend
}, callback)
}

@JSName("setState_scala")
@JSName("setState_scala_6")
@inline final def setState(fn: (State, Props) => State, callback: () => Unit): Unit = {
this.asInstanceOf[PrivateComponentClass].setStateR((ps: js.Object, p: js.Object) => {
val s = fn(readStateValue(ps), readPropsValue(p))
Expand Down Expand Up @@ -137,7 +137,6 @@ abstract class DefinitionBase[Props, State, Snapshot](jsProps: js.Object) extend

def componentDidCatch(error: js.Error, info: ErrorBoundaryInfo): Unit = {}

@JSName("render")
def render(): ReactElement

if (defaultBase != null) {
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.2.8
sbt.version=1.3.2
31 changes: 21 additions & 10 deletions tests/src/test/scala/slinky/core/ComponentTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,22 @@ object TestComponentExtraApply extends ComponentWrapper {
}
}

object TestComponentForSetStateCallback extends ComponentWrapper {
type Props = Int => Unit
type State = Int
object TestComponentForSeqState extends ComponentWrapper {
type Props = () => Unit
type State = Seq[String]

class Def(jsProps: js.Object) extends Definition(jsProps) {
override def initialState: Int = 0
override def initialState = Seq.empty

override def componentDidMount(): Unit = {
setState((s, p) => {
s + 1
}, () => {
props.apply(state)
})
setState(state :+ "hello")
}

override def render(): ReactElement = {
override def render() = {
if (state.nonEmpty) {
props.apply()
}

null
}
}
Expand Down Expand Up @@ -319,6 +319,17 @@ class ComponentTest extends AsyncFunSuite {
promise.future
}

test("setState with Seq state runs correct overloaded definition") {
val promise: Promise[Assertion] = Promise()

ReactDOM.render(
TestComponentForSeqState(() => promise.success(assert(true))),
dom.document.createElement("div")
)

promise.future
}

test("Can construct a component and provide key") {
val element: ReactElement = TestComponent(_ => ()).withKey("test")
assert(element.asInstanceOf[js.Dynamic].key.toString == "test")
Expand Down

0 comments on commit c899120

Please sign in to comment.