-
Notifications
You must be signed in to change notification settings - Fork 2
Errors and warnings overview
If setState()
returns a Promise
, an onDone handler (and optionally an onError handler) is required to do any state
changes.
Yes:
setState(
'reason',
async () => {
state1.counter++;
const value = await fetchSomeData();
return (value % 3 === 0) ? 'hello' : 'howdy';
},
value => { state1.greeting = value }, // <-- onDone handler
error => { state1.errors.push(error.message) } // <-- onError handler
);
No:
setState(
'reason',
async () => {
state1.counter++;
const value = await fetchSomeData();
return (value % 3 === 0) ? 'hello' : 'howdy';
}
)
State can not be manipulated outside of setState()
.
Yes:
setState('reason', () => state1.counter++);
setState(
'reason',
() => Promise.resolve(state1.counter + 1),
newCount => { state1.counter = newCount }
)
No:
state1.counter++;
state1.counter = state1.counter + 1;
If setState()
returns a Promise
, an onDone
handler needs to be provided to further change the state after the
promise has resolved (while still in the same setState
context).
Yes:
setState(
'reason',
async () => {
state1.counter++;
const value = await fetchSomeData();
return (value % 3 === 0) ? 'hello' : 'howdy';
},
value => { state1.greeting = value }, // <-- onDone handler
error => { state1.errors.push(error.message) } // <-- onError handler
);
No:
setState(
'reason',
async () => {
state1.counter++;
const value = await fetchSomeData();
state1.greeting = (value % 3 === 0) ? 'hello' : 'howdy';
}
)
setState(
'reason',
async () => {
state1.counter++;
const value = await fetchSomeData();
state1.requestCount++; // <-- state changed after await
return (value % 3 === 0) ? 'hello' : 'howdy';
},
value => { state1.greeting = value }, // <-- onDone handler
error => { state1.errors.push(error.message) } // <-- onError handler
)
A call has been made to watchState(_, options)
without providing a callback for when state changes.
-
options
- options object which describes how to watch the state- An error will be thrown if both
onChanged
andonEachChange
areundefined
(one of them needs to be set).
- An error will be thrown if both
Namespaces must be unique. When Diffx stores your state it does so by having an object with all state in, where
the namespace
is used as the key, and the state is the value.
createState('myUniqueNamespace', { a: 1 });
createState('my other unique namespace', { b: 1 });
// Diffx will internally store the above as
const rootState = {
myUniqueNamespace: { a: 1 },
'my other unique namespace': { b: 1 }
}
If createState is called again with the same namespace
, Diffx will throw an error.
If you are developing in e.g. React, the hot reload of the code will automatically call createState
with the same
namespace again. To avoid throwing, use setDiffxOptions({ devtools: true })
.
If running with setDiffxOptions({ devtools: true })
, running createState(namespace)
with the same namespace
multiple times will trigger a replacement of the state. This is to allow it to work with hot reload, but also to notify
in case it was unintended. See core-14 for more info.
The first argument provided to setState()
must be of type string
, explaining why the state will be changed.
The second argument provided to setState()
must be of type function
, wrapping changes to the state.
setState('incrementing the counter', () => state1.counter++);
The state has been paused (possibly by selecting a state in the Diffx devtools). Changes to the state are ignored and logged to the console while paused.
The mutatorFunc provided in setState(reason, mutatorFunc)
returned a Promise
that threw an error.
To catch the error, an error handler needs to be provided.
setState(
'Testing an asynchronous throw',
() => new Promise(() => { throw new Error('I am a promise that threw'); }),
() => {}, // <-- onSuccess
error => { /* do something when the error occurs */ }
);
This error occurs when setState()
is nested inside setState()
until it reaches the maxNestingDepth
set
in setDiffxOptions({ maxNestingDepth: <integer> })
(default is 100).
Reaching the max nesting depth is usually caused by watchState
calling setState
which in turn triggers watchState
again, resulting in a loop.
const state1 = createState('my state', { counter: 0 });
// this will result in a loop
watchState(
() => state1.counter,
{
emitInitialValue: true,
onEachSetState: newValue => {
setState('increment counter', () => state1.counter++);
}
}
);
This error occurs when persistence has been enabled globally
setDiffxOptions({ persistence: true })
or for a specific state
createState(namespace, initialState, { persistence: true })
without specifying { persistenceLocation }
.
The persistenceLocation is expected to have the same API as localStorage
/sessionStorage
,
and is used by Diffx to persist the state.