Tungsten

State

Tungsten uses javascript Proxies to intercept assignments to component state, removing the need for a setState method.

Unlike React class component state, which is immutable, the Tungsten state object is entirely mutable, making it much easier to work with.

For example, in this slightly contrived example, with react the following code would not work, because the state is not updated until the next update.

updateFirstName = (firstName) => {
this.setState({ firstName })
this.updateFullName()
}
updateFullName()
this.setState({ fullName: this.state.firstName + " " + this.state.lastName })
}
and updating objects is downright awkward, leading to the suggestion to use 'flat state'
updatePhone(phone) => {
this.setState({ form: { ...this.state.form, phone }})
}
Tungsten allows simple and ordinary JS techniques
updateFirstName = (firstName) => {
this.state.firstName = firstName
this.updateFullName()
}
updateFullName()
this.state.fullName = this.state.firstName + " " + this.state.lastName
}
updatePhone(phone) => {
this.state.form.phone = phone
}
The Proxy method also supports all assignment and modification operators such as this.state.x *= y and this.state.x++

Mutable state safety

Mutable state does introduce a single primary risk: if the state is modified during render, this could lead to a "torn render", where the state has changed part way through, and the final content is not coherent. Avoiding this is simple: don't update state in the content function, and don't call any mutating functions from the content function. State should be set/mutated only on init, and in response to events, such as user events or data responses.

Although state is mutable and immediately updated, the component will only updater after all current synchronous code completes. If you await something asynchronous between state updates, an update will occur after your code starts to wait for the async operations (not all calls of async functions lead to waits, async functions are run synchronously, until the point that waiting is required)