Comments (32)
@yantakus Looks like I understand what you are looking for. I will try to create some 'starter template app'. Do you know an example of it for Redux or Mobx or other lib? I need some inspiration... I can think of TODO list editor...?
from hookstate.
Hello there,
I am writing a piano learning application https://moonpiano.praisethemoon.org/ with React and Electron. I have been using redux for handling Piano Keyboard events and damn how slow it was. I have been searching for alternatives to improve performance, and recently I have considered dropping React overall due to poor performance. Hours lost in the Chrome's performance tab trying ro figure out how to improve things, hΓ©las, nothing working.
Just few minutes ago, I came a cross this library, I thought I might give it a try. I had to encapsulate my class components with functional components in order to use the hooks available here.
Results? This library saved my project and my hopes! I am so impressed by the performance gain! I just had to rewire the events to use this library. I still use redux for other stuff, but for frequent events, they working like a charm.
from hookstate.
This is very nice article. I like the performance comparison animation.
BTW, Preact by itself will not give you the performance boost if you have got "rerender due to state update" performance problems. I have compared Preact VS React performance with hookstate: Preact is about 2x times faster than React on the same large table performance demo. However, I am not a fun of preact - to many risks to switch the engine - far easier to minimise rerendering in your app (using Hookstate is one method), which you have control over.
from hookstate.
Hi @avkonst. Great library, impressed with the performance examples!
Still would be very useful to see an example app built with hookstate. Codesanbox is a very good tool for this. I mean it would be great to see an app with multiple components in different places of an app (far away in tree so it is not reasonable to pass state via props) that share the same state values.
I'm considering to try it in my app that is having performance problems, but I don't see an easy and convenient way to share global state. Checked all the examples and any of them describes this use case.
prefer to have global stores not published externally from a module / library
You don't explain the reason behind this suggestion. It would be cool to understand it in detail.
from hookstate.
@praisethemoon checked your video. This is very impressive performance demo. And I guess this is not the limit.
from hookstate.
Available online: https://hookstate-example-app.netlify.com/
from hookstate.
I have added 'Used by' section in the docs: https://github.com/avkonst/hookstate#used-by
@praisethemoon, please let me know if you are happy / unhappy about yours being mentioned.
from hookstate.
Hi @eddielee394 .
Yes, it is used for web app (SPA) and cordova wrapped mobile app - both are managing a lot of data and some of it is real-time watched / changed. I can not name the apps today for legal reasons, but hopefully will be able to name some time soon.
Regarding the design pattern: it is similar recommendations when to use local variable, when to use global variable, when to use module encapsulated variable versus externally published. You can go with one global store, with many global stores, with all being local stores passed as props to children components, or use the mixture of approaches (what I do, depending on a case and my engineering experience)
- prefer local state if it is created and consumed by a component and only it's near (not deeply nested) children
- prefer global state when multiple independent component consume it, i.e. component staying not close in the DOM tree hierarchy
- prefer global state if it can be created or mutated outside of a mounted component, i.e. when a component is not yet (or already not) mounted
- prefer to have global stores not published externally from a module / library
- if a state is published externally (i.e. part of a library interface), publish the wrapped version of it using the
transform
argument of the create/useStateLink functions. - prefer multiple global stores for separate independent states (for example, state for user settings, and state for core application data could be separate), it will be easier to refactor/maintain/move things around later.
- if you used to have one global app state with many reduce actions hitting one interface, go with one state, it will be easier to understand for you - you will be always able to split it later with a bit of refactoring. One global - or many split global states will perform equally well - thanks to the usage tracking optimisations done by the Hookstate.
These are the generic guidelines on top of my head I found useful so far.
from hookstate.
The demo application with code samples is a good example of possible application architecture - every individual example uses it's own states, but can share it when many components need to share the state. Just general programming common sense.
Please let me know if the above answers your questions or you would like more information.
from hookstate.
Thanks @praisethemoon . Very nice feedback. I am happy it helped you.
Please consider to help the project to grow by spreading few words about it in blogs, forums, Q&A, etc. Posting your story about replacing slow redux is a nice one to share broadly. Thanks in advance.
from hookstate.
@avkonst https://praisethemoon.org/hookstate-how-one-small-react-library-saved-moonpiano/. That's for a start, gonna do the rest whenever I get the chance!
from hookstate.
@praisethemoon FYI: when I attempted to leave a comment on your blog post, I have received the response about invalid capture verification. I have tried the second time and it worked.
from hookstate.
Thank you for the feedback about preact
! The currently published MoonPiano version works like a charm but the code is a bit messy, I had to rewrite it now and improve performance. Inorder to move to preact
I would have to rewrite it a third time π
I will take your advice and focus on incrementally improving the performance!
I have got your reply, let's move the discussion there :)
from hookstate.
One way to improve the code is to get rid of class components gradually and move them to functional with hooks. It improved and simplified a lot for me.
from hookstate.
So you think it is better to get rid of redux? I don't think it works well with functional components. Right now the way I used Hookstate is by encapsulating components by functional components.
from hookstate.
from hookstate.
To be honest, hookstate is way easier! The only advantage of Redux (and others probably) that I can think of is that you can trace their updates in developer tools (which I do not use as much my self). I am going to progressively converge to 100% hookstate. This new performance gain really refreshed my motivation π
from hookstate.
There are 2 ways to trace updates with Hookstate: 1) attach Logger plugin and 2) use React developers tools and click "Highlight updates". The combination of these was sufficient for me so far. How would you like to see it done better?
from hookstate.
Oh wait I didn't know of the logger plugin! Thanks for pointing that out! Since I am using Electron, the react-dev-tools that is running with my app does not have the highlight updates features (it was removed recently I think). In any case, I will give it a try and share my feedback!
from hookstate.
As far as I know electron uses same Dev tools as Chrome. And they added highlight updates back recently.
from hookstate.
Good to hear that! Yes electron actually loads chrome's extensions from disk, so I just gotta update react-dev extention and hope for the best π
from hookstate.
@praisethemoon hint for you: you can use Hookstate in your class components with help of StateFragment
. Something like this (pseudo code):
class MyComponent extends React.Component {
var store = createStateLink('initial state') // this is locally created state, but the same will work with global state
// also, you would need to call store.destroy() on component unmount, which is essential for some plugins. There are no plugins here, so no destruction is needed.
render() {
return <StateFragment state={this.store}>{storeLink =>
<input value={storeLink.value} onChange={e => storeLink.set(e.target.value)}/>
}</StateFragment>
}
}
Let me know if it works. I believe it should.
from hookstate.
The reason for "prefer to have global stores not published externally from a module / library" - if a store is not used outside of components within a module, do not make the store accessible to other modules. I guess I try to say - apply the same common sense principles if a store was just a plain variable of some other type (let's say a string)
from hookstate.
I agree with @yantakus regarding global state usage. For example, if we were dealing with a redux app we'd pass our store onto a provider HOC component, which then allows us to access the different parts of the store within our components using the useSelector()
hook.
If we need to deal with side effects that may update global state (like an api request), we'd use useDispatch()
in whatever component needs to dispatch that action, then the action calls the reducer, state gets updated, etc.
The challenge for me is how do we translate that state management paradigm when using hookstate, because I'd really like to get away from using redux and all of the issues that come with it's implementation.
from hookstate.
Do you know an example of it for Redux or Mobx or other lib?
Redux:
https://github.com/atulmy/crate
https://github.com/flexdinesh/react-redux-boilerplate/
https://github.com/hidjou/classsed-redux-hooks
Mobx:
https://github.com/mobxjs/awesome-mobx/blob/master/README.md#example-projects
https://github.com/mobxjs/mobx-react-boilerplate
from hookstate.
@avkonst make sure to check my updated post, I have added a video demonstrating the new performance!
from hookstate.
@avkonst Yes I agree TODO list would be a great example of an app built with hookstate.
from hookstate.
@praisethemoon , @yantakus , @eddielee394 Could you please review the sample application and suggest improvements? or advise if the example application with Hookstate is sufficient to close this issue?
from hookstate.
@avkonst Thanks for the example app. Well done! This is exactly what I needed. Now I see how it can be implemented in my existing app without rewriting it completely. I just have to rewrite one file that creates app state and exports it.
from hookstate.
@avkonst This makes perfect sense now. Thanks for taking the time to put together that example app.
from hookstate.
I have added the section 'Quick Start', which refers to the example app now: https://github.com/avkonst/hookstate#quick-start
from hookstate.
Looks very good to me! Thanks for sharing it :) Looking forward to see this library grow!
from hookstate.
Related Issues (20)
- Any showcase how to work with Immutables? HOT 2
- Resource leak with `useHookstate` HOT 2
- Is this lib still being updated? HOT 3
- Request: throw error when trying to assign nested state to a Proxy object HOT 2
- Migration from 3 to 4 HOT 4
- Localstored - optional initializer HOT 1
- https://hookstate.js.org/docs/exceptions/#hookstate-106 is killing me HOT 1
- What is the meaning of `E` in State<S, E>? HOT 1
- Injecting React-Router-dom instance into the store HOT 1
- one of my favourite projects really HOT 4
- More than 5 extensions loading HOT 2
- Creating a global object using hookstate, but unable to find the property when using it. HOT 2
- How to handle file objects in v4? HOT 1
- Isolating global states between tests HOT 4
- state.attach is not a function
- Combine extensions HOT 3
- Nextjs: localstorage is not defined HOT 6
- having problem with getting rid of proxy HOT 2
- Broadcasted state extension not working HOT 2
- 106 EXCEPTION 'Cannot Convert Undefined Value to Object' Error when setting and getting global store state in two seperate components HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hookstate.