Next piece of code shows how we can obtain a state in Effector in a right way. This kind of state retrieving provides state consistency, and removes any possible race conditions, which can occur in some cases, when using getState.
sample({
source: $form,// Take LATEST state from $form, and
clock: submitted,// when `submitted` is triggered
target: sendFormFx,// pass it to `sendFormFx`, in other words -> sendFormFx(state)
//fn: (sourceState, clockParams) => transformedData // we could additionally transform data here, but if we need just pass source's value, we may omit this property
})
So far, so good, we've almost set up our model (events, effects and stores). Next thing is to create event, which will be used as onChange callback, which requires some data transformation, before data appear in setField event.
const handleChange = setField.prepend(e=>({
key: e.target.name,
value: e.target.value,
}))// upon trigger `handleChange`, passed data will be transformed in a way, described in function above, and returning value will be passed to original `setField` event.
Next, we have to deal with how inputs should work. useStoreMap hook here prevents component rerender upon non-relevant changes.
constField=({name, type, label})=>{
const value =useStoreMap({
store: $form,// take $form's state
keys:[name],// watch for changes of `name`
fn:values=> values[name]||'',// retrieve data from $form's state in this way (note: there will be an error, if undefined is returned)
})
return(
<div>
{label}{' '}
<input
name={name}
type={type}
value={value}
onChange={handleChange /*note, bound event is here!*/}
/>
</div>
)
}
And, finally, the App itself! Note, how we got rid of any business-logic in view layer. It's simpler to debug, to share logic, and even more: logic is framework independent now.
constApp=()=>(
<form
action="void(0)"
onSubmit={submitted /*note, there is an event, which is clock for sample*/}>
This code is way shorter, yet has code duplication, lower scalability and less reusable. In some cases, usage of getState may cause state inconsistence, race conditions.
This example shows, how you can manage state with uncontrolled form, handling loading of data, create components which dependend on stores, transform data passed between events.