@composi/runtime:
Immutability
Program State is Mutable
By default a program's state is mutable when you have access to it inside both the update and view methods. Hopefully no one would ever modify state from the code for rendering the view. Update, on the other hand, is how you modify a program's state. For simple examples this is probably not going to be a problem. At the very least, you can use destruction to create a shallow copy of program state:
function actions(state, msg) {
// Clone the state using destructuring:
const prevState = {...state}
return Msg.match(msg, {
// Check for the message tag:
'addItem': value => {
prevState.fruits.push({ key: prevState.newKey++, value })
// Render view and update program state by return the clone:
return prevState
},
// Check for the message tag:
'deleteItem': key => {
prevState.fruits = prevState.fruits.filter(item => item.key != key)
// Render view and update program stateby return the clone:
return prevState
}
})
}
Deep Clone
If your app and data are complex, you will probably want to create a deep clone of your data. You can do that inside the the update function just like we did with destruction above. Just import the clone
function from @composi
namespace:
import { h, render, run, union } from '@composi/core'
import { clone } from '@composi/clone'
function actions(state, msg) {
// Clone the state:
const prevState = clone(state)
return Msg.match(msg, {
// Check for the message tag:
'addItem': value => {
prevState.fruits.push({ key: prevState.newKey++, value })
// Render view and update program state by return the clone:
return prevState
},
// Check for the message tag:
'deleteItem': key => {
prevState.fruits = prevState.fruits.filter(item => item.key != key)
// Render view and update program stateby return the clone:
return prevState
}
})
}
Using the above technique of cloning the state with clone
means that the program state won't be updated until the action returns it.