unistore
unistore copied to clipboard
Show how to reuse actions within actions in docs?
This works... maybe worth adding to the readme.
// If actions is a function, it gets passed the store:
let actions = store => ({
// Actions can just return a state update:
increment(state) {
return { count: state.count + 1 };
},
// The above example as an Arrow Function:
increment2: ({ count }) => ({ count: count + 1 }),
// Async actions are actions that call store.setState():
incrementAsync(state) {
store.setState(this.increment(state));
setTimeout(() => {
store.setState({ count: store.getState().count + 1 });
}, 1000);
},
});
Hmm i tried that, but my this
is bound to onClick if we refer to the example in the README.
edit and binding each function to actions object for correct context seems a bit tedious, it would be nice if it was passed in as parameter al la FormidableLabs/freactal where they are called effects
@jaredpalmer Your async action increments the count twice, FYI.
@davidchase Binding of this
is a flaw in the javascript language, not unistore. You can just initialize all the actions as pure functions and return and object that references them so you're not using this
for anything. E.g.
export default (store) => {
const increment = (state) => {
return {
count: state.count + 1,
}
}
const incrementAsync = (state) => {
setTimeout(() => {
store.setState(increment(state))
}, 1000)
}
return {
increment,
incrementAsync,
}
}
Might be worth changing the readme to more explicitly spell out the outer function and calling contexts:
// If actions is a function, it gets passed the store:
function createActions(store) {
const actions = {
// Actions can just return a state update:
increment(state) {
return { count: state.count + 1 };
},
// The above example as an Arrow Function:
increment2: ({ count }) => ({ count: count + 1 }),
// Async actions are actions that call store.setState():
incrementAsync(state) {
store.setState(actions.increment(state));
setTimeout(() => {
store.setState({ count: store.getState().count + 1 });
}, 1000);
}
};
return actions;
}
Otherwise I'd recommend something like what @ehaynes99 suggested - avoid context entirely.
I'm trying to avoid the wrapping/context to have my actions.js be a collection of pure functions but it makes hard to have a "thunk" like functionality. How can I achieve something like the following without having to import the store into actions.js and without wrapping actions into a context/function?
const setName = (state, name) => {
state.name = name;
validateName(state, name); //async but nobody will get this state update?
return state:
};
const validateName = async (state, name) => {
const isValid = await ... // axios stuff...
state.nameIsValid = isValid;
return state; // wait! this state is STALE, because I'm returning an old version of state
};