3 ms·
I've just started another side project using React with redux. One of my goals is to keep my code as simple as possible while still being able to build a large
by davedx 9y ago
I've just started another side project using React with redux. One of my goals is to keep my code as simple as possible while still being able to build a large application.
To keep it simple, I'm not using react-redux (I often try to avoid this), and I generally pass the entire store down through all child components, again to keep it simple. My top level app with its simple navigation code subscribes to the redux store and sets its state from it. My router is just a bunch of statements like {pageName === 'connnections' && <ConnectionsPage {...props}}.
To avoid too much boilerplate, I find most of the time all you need are some helper functions. I have a helper function called 'action' that I call like action('LOAD_SOME_DATA') that dispatches on the store with type: 'LOAD_SOME_DATA'. I use a simple 'getIn' function to access nested data, and I mutate data in my reducers with object-path-immutable. Everything is clean and easy to read.
I believe one of the biggest problems with the React community is the constant bleed of 'performance' into app design and development. Premature optimization is everywhere.
Guess what, most apps won't need immutable data and free componentShouldUpdate checks, memoized selectors, or subscribing to subsections of the store using complicated 'connect'/high order component plumbing.
The one time I actually had a perf issue with React was when I had a GIGANTIC list of data (showing all the active salespeople in our company -- we have a lot), which due to me storing form state in redux was being completely re-rendered every keystroke.
The solution wasn't to add react-redux or start using immutable data - it was to add paging and filtering. I improved performance, but more importantly, the UX of the app with this.
If your React app really is so huge and complex that it needs reselect, react-redux, react-router, great stuff -- you are obviously building software for a successful product with lots of feature requirements. Most apps I've worked on never got to this level of complexity.
- Nimelrian 9y agoPassing the store (or in general, your application state) down from each component to their children has one big flaw: It reduces your components' reusability in other projects. You can circumvent this by creating a component at the top level of your application which holds the state and passes it down via React's context. The state-dependent components can then pull the state from context where they need it. By doing so, you basically reinvented react-redux, which works just like this (+ the performance optimizations). Regarding your issue with the complete app rerendering on a single keystroke: This is a result of you passing down the entire store to each component. Since you still edit the store in an immutable way, on every keystroke you create a new store object and React rerenders everything because the store prop changed. I'm also confused how using paging/filtering would help with this. Another advice would be to not store form state in redux. Keep your redux store only for your actual model application state. Keep forms/temporary state in your components and move it to your model redux store once it is done/baked.
- acemarke 9y agoI'm _very_ curious: why do you feel you need to "avoid" React-Redux? There was a similar thread on Reddit a few days ago, asking why the OP should bother using React-Redux [0]. I'll paste the main part of my reply: > First, while you can manually write the code to subscribe to the Redux store in your React components, there's absolutely no reason to write that code yourself. The wrapper components generated by React-Redux's connect function already have that store subscription logic taken care of for you. > Second, connect does a lot of work to ensure that your actual components only re-render when they actually need to. That includes lots of memoization work, and comparisons against the props from the parent component and the values returned by your mapStateToProps function for that component. By not using connect, you're giving up all those performance improvements, and your components will be unnecessarily re-rendering all the time. > Third, by only connecting your top-level component, you are also causing the rest of your app to re-render unnecessarily. The best performance pattern is to connect lots of components in your app, with each connected component only extracting the pieces of data it actually needs via mapStateToProps. That way, if any other data changes, that component won't re-render. > Fourth, you're manually importing the store into your components, and directly coupling them together, thus making it harder to test the components. I personally try to keep my components "unaware" of Redux. They never reference props.dispatch, but rather call pre-bound action creators like this.props.someFunction(). The component doesn't "know" that it's a Redux action creator - that function could be a callback from a parent component, a bound-up Redux action creator, or a mock function in a test, thus making the component more reusable and testable. > And finally, the vast majority of apps built using React and Redux use the React-Redux library. It's the official way to bind the two together, and doing anything else will just confuse other developers looking at your project. > So, part of the issue is you're not using React-Redux and connect, and part of the issue is you're using an inefficient pattern for pulling data from the Redux store into your React components. So no, many apps don't need to spend tons of time optimizing performance, but at least part of that is because `connect` already handles a lot of that for them. There's also other reasons for immutability, per my original post for this thread: time travel debugging, testability, and ability to reason about state updates. Also, in regards to the "re-rendering on every keystroke" issue, my post "Practical Redux Part 7: Form Change Handling" [1] shows off a React component I made that specifically helps buffer those for fast form updates, while debouncing the number of Redux actions dispatched. [0] https://www.reddit.com/r/javascript/comments/6hperk/i_use_react_and_redux_but_never_reactredux_what/ https://www.reddit.com/r/javascript/comments/6hperk/i_use_re... [1] http://blog.isquaredsoftware.com/2017/01/practical-redux-part-7-forms-editing-reducers/ http://blog.isquaredsoftware.com/2017/01/practical-redux-par...