-
-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How does Kea compare to other state management frameworks? #106
Comments
I find myself often agonizing over this topic all the time. Am I using the best state management system/library for my use case? Is there one that's best for most/all use cases?
Overall I would say that it's pretty arbitrary for personal projects so long as it works and doesn't have a drastic negative impact on dx or performance. As for bigger projects i.e. those that will potentially be continued and maintained by others, I'm inclined to go with whatever has the best dx and community support. For me right now that's |
Hi, I think this thread is very interesting. I didn't know about Kea until today, and it seems a good solution. But I can't really see the difference between things until I see them in practice. Would you mind to implement with Kea this dumb example I did to try Recoil? |
Hi @Teomik129 and @Josema! @Teomik129, thanks for sharing your experience! I submitted Kea to both awesome state management lists. I hadn't heard of rematch until now, but despite their slogan of "Rematch is Redux best practices without the boilerplate." it seems to come with quite a bit of boilerplate. Namely those Using context for state seems like a cool approach. I hadn't read that article before, but it seems like this can work well for small apps. However, React-redux in their v7 refactor migrated away from using context due to performance reasons. I also recently had a chat with someone (hi @lovekaizen) who said that they're running into issues with context as in their app every component gets re-rendered when something in the context changes. -- Hi @Josema, thanks for writing! Recoil seems to be the new hype these last days. It's a great idea to compare it and Kea. I implemented the example you gave with Kea here: There are more than one way to do this with kea, so I did two implementations there. |
Thank you for taking the time to implement it in kea! Two question, is it mandatory to use react-redux as Provider? Is not an extra kb for the bundle just for that? Why the components render/print twice on every click? I mean, when I click on the red button, console.log should print:
But is printing:
|
Hi @Josema
|
Hi again @Josema , I figured out what was up with the double render. The codesandbox wrapped the The docs on StrictMode say the following:
So the double render was caused by React making sure the app is compatible with its upcoming concurrent mode. This Mystery solved! :) |
That's cool. I see is working properly now. I was thinking on creating a performance test to see how Kea and other frameworks (even React standalone) handle this shared state problem. Do you know any test of this kind that has been already made it? |
HI there, The port was almost straight forward by converting the Redux Toolkit feature "slices" to Kea's "logic" components. The rest of the project is more or less a 1:1 copy. As an overall personal impression in comparison to Redux Toolkit Kea helps you better to
Especially I like the clean design of the overall framework. You can easily get the overall idea by just reading the framework code. Based on this, by using the generic plugin mechanism, it is comparably simple to enhance the framework with custom abstractions that fit your project specific needs. |
Hey dude, Kea is cool, what do you think of concent? |
The only thing I have it to compare with is plain-old-redux. I would take Kea over Redux any day:
|
Making Everything in 1 logic file or one dir is really a good way to improve soft engineer's develop experience, look at the code snippet below that comes from concent: // logic.js
import { configure } from 'concent';
const delay = ()=> new Promise(r=> setTimeout(r, 1000));
const state = ()=> ({num:1, bigNum:100});
const reducer = {
async initState(){
await delay();
return {num: 10, bigNum: 1000};
},
inc(payload, moduleState){
return {num: moduleState.num +1 };
},
async asyncInc(){
await delay();
return {num: moduleState.num +1 };
},
};
const computed = {
// only num change will trigger this computed fn
doubleNum: ({num})=> num *2,
};
const lifecycle = {
mounted: (dispatch) => dispatch("initState"), // [optional] triggered when the first ins of counter module mounted
willUnmount: (dispatch) => dispatch("initState") // [optional] triggered when the last ins of counter module unmount
};
// configure them to a module named counterMod
configure('counterMod', {state, computed, reducer, lifecycle}); then you can use it in anywhere you want // for class component
@register('counter')
class DemoCls extends React.Component{
render(){
const { state, mr, moduleComputed } = this.ctx;
// here if read num, it means current ins render dep keys is ['num']
return <button onClick={mr.inc}>{state.num} {moduleComputed.doubleNum}</button>
}
}
// for function component
function DemoFn(){
const { state, mr, moduleComputed } = useConcent('counter');
return <button onClick={mr.inc}>{state.num} {moduleComputed.doubleNum}</button>
} |
@fantasticsoul that is a legit yet totally different approach from Kea. With kea the same code would look something like this: const delay = () => new Promise((r) => setTimeout(r, 1000))
const logic = kea({
actions: {
setValues: (num, bigNum) => ({ num, bigNum }),
inc: true,
asyncInc: true,
},
defaults: {
num: 1,
bigNum: 100,
},
reducers: {
num: {
inc: (state) => state + 1,
setValues: (_, { num }) => num,
},
bigNum: {
setValues: (_, { bigNum }) => bigNum,
},
},
listeners: ({ actions }) => ({
asyncInc: async () => {
await delay()
actions.inc()
},
}),
selectors: {
doubleNum: [(s) => [s.num], (num) => num * 2],
},
effects: ({ actions }) => ({
afterMount: async () => {
await delay()
actions.setValues(10, 1000)
},
}),
})
function DemoFn(){
const { num, doubleNum } = useValues(logic);
const { inc } = useActions(logic);
return <button onClick={inc}>{num} {doubleNum}</button>
} The example is very specific of course, and seems to be tailored to your library's features. Thus the kea code is definitely longer as I had to use many different features to get exactly the same functionality. I would argue it's still easier to understand though :). Kea's approach is also easier for code splitting, as the slice of logic is always passed via ES imports ( In any case, good luck with your library! :) |
I know that I'm a bit late to the game, but I just wanted to call out that, after a few hours of exploring Kea, I love it. The boilerplate of Redux typically made it so I had to weigh the value of time-travel debugging and determine if the complexity of the application would benefit from time-travel - rarely did I end up pulling in Redux. I generally stuck with pure React hooks that I would lift up into their own contexts as needed and when I did need complexity, foregoing flux in favor of state charts and state machines was the route that I often chose purely from a DX perspective. Kea is to Redux/flux what xState is to state machines - and I find it to be a total game-changer. Thanks for the great React state framework and all of the surrounding tooling! |
Hi everyone! I get often asked to compare Kea with X, where X is some other approach to managing state in React. Be it easy-peasy, redux-toolkit, mobx, dva, react context + hooks, etc. (incomplete list)
Unfortunately I never have a good answer, as I haven't used any of them extensively and for big projects. I have just read the readmes, which is not enough for a smart comparison.
I believe Kea is something special in the react world and that it strikes a beautiful balance between simplicity vs flexibility vs joy vs power. However, while many people I've spoken to also seem to agree with this, I'm obviously really biased here.
Thus, I'm asking the internet: please share if you have any experiences with any of the other frameworks... and especially with how they compare to Kea when writing large real world applications, where state management gets pretty complex. I'm not interested in TodoMVC.
Your answers can be anything from "Kea rocks" to "Functional programming is the scourge of the earth and you're better off burning coal for heat" to "In a huge app with X state trees, we ran into issues X, Y, Z with framework B after we did Q, N and K".
Please keep it civil though!
My hope for this thread is that I can either: 1) learn something new to make Kea even better... or 2) prove that it really is as awesome as it seems!
I'll leave you with two quotes:
Kea is a complex system that works as well as it does because it rose out of a simpler system over time. Kea 2.0 made this complex system much simpler to use and as a result, I think it's the best way to manage state in the React ecosystem.
Prove me wrong!
The text was updated successfully, but these errors were encountered: