Better approach to create react-redux layout header component - reactjs

I'm going to create a large scale application with react and redux and start to build the header component of the layout very first time. The layout header will have 4 child parts.
1. Icon that will show all the online users after clicking on it
2. Icon that will show latest 10 notifications after clicking on it
3. Icon that will show latest 10 messages received after clicking on it
4. Logged in user name that will be dropdown button to show some "My profile, logout, account setting" navigation links.
As I've read about redux at so many places that we must have as less as possible stateful components. So by keeping this concept in mind, I thought to have only one header smart container with a header state consisting default states for all icons like
{headerOnlineUsers:[], headerMessages:[], headerNotifications:[]}.
So if I follow the redux best practice and create only one smart header container with 4 different dumb components, the each and every time the state of any of them is changed, the whole header container will get re-rendered.
But I want to re-render only the state changed component.
For example, If I get a user joining the chat through websocket, It will dispatch an action and the reducer will update the headerOnlineUsers list of the state. But In this case I want my only online users component to be re-render not the whole header container.
Can anybody please suggest me the best approach to implement this kind of layout.

I would not go for your option, but would prefer a more granular approach.
What if you split the header in 2 later on, or want to display the button somewhere else ?
What if you have another version of your header for a subsection of the website ? You would need another container that gather again all the info.
The logic in general in redux is to separate what is data-sensitive and what is not. Your individual lists are data sensitive, the header in itself has no reason to be so far. What's more, if you want to attach actions to the icons it will quickly become messy to bring back thoses actions to the header and then its container, and even messier if you ever need to move them.
The way I would do it (and the way I do it right now as I halso develop quite huge app with react and redux), would be to have a store with those 3 lists of items, and then 3 containers, one for each icon/dropdown that links one aprticular list to the component.
Then the header is just a stateless function holding all the containers together. This way if you ever need to move one button somewhere else or reuse it, you just import the container and voila!

React.js will take care of only re-rendering what is required. So this problem is already solved for you :-)
What you plan to do sounds sane to me, I just would change one bit: The smart header container should not use internal state. Instead, your redux store should look like this:
{headerOnlineUsers:[], headerMessages:[], headerNotifications:[]}
and you should pass the redux store into the smart header container (have a look at the connect function in the redux documentation). This way, you can use the redux store contents in your component via this.props, and that's it.

Related

how to develop a screen where this similar/same screen is presented in multiple flows

I am developing a website in React.
In this website I have a screen - lets call it "book-an-appointment"
And I have multiple flows:
book an appointment for existing client
book an appointment for non-existing client
book-an-appointment is part of flow 1 and 2, with slight differences:
some buttons that are shown only in one of them
"next" button that takes the user to a different screen
it affects differently on the funnels
of course each one of them is in a different URL
and more...
Question: Which approach is best practice in developing such screen in react?
options I thought about are:
Creating A single screen that shows the relevant buttons and actions according to the state
Duplicating the screen for each flow (because of the small differences in it)
I am quite new to react. tried to look for an answer here and in google but couldnt find my answer.
In that case I would just use one Parent component with ether two child components with the different flows. You can make one JSON object where conditionally you add specific keys and you can later check if the isExisting field exists for example what kind of booking it is and show a the existing user flow component.
You could do it like that or have one component that just conditionally hides fields depending on what type of booking it is. In this case you would use conditional rendering. See the article below for more info.
https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator

Use cases for when not to use redux?

I was always wondering if I should use redux store all the time even when it's not really necessary.
For example:
I have form with select field that has some options I fetch from API. Let's imagine that form is for adding new car listing and select options are car models. Should I directly call API from component and display options or should I create store CarModels or something like that and store results from API there and then map those values to state in component?
I have "Favorites" feature, when you click heart next to some item (let's say a car), do I need to go through dispatching all events FAVORITE_CAR_REQUEST, FAVORITE_CAR_SUCCESS etc... or is it good enough to just call API directly from component (using some kind of api-service of course).
It's related to question above. If I have screen where I show favorites, I should then probably have store and connect everything with actual favorite action so I update the list. On new favorite, API will return favorited item, should I push that one in list of favorites already in store or should I just load again latest list when user opens up the favorites screen?
Thanks in advance.
I think this is a perfectly valid question. What I feel like you're trying to ask is if you could/should mix react state and the redux store. The answer is sure! Just think about where you need to use that part of state before deciding where to store it. If you need a part of the state in multiple components, it probably makes sense to use Redux. If you only need state locally, perhaps to set form validation errors, maybe use react's state management if you feel like it. React and redux are both meant to be flexible, so as long as you're consistent in when you use the redux store and react state you should be good.
I found this article that also explains this pretty well: https://blog.jakoblind.no/is-using-a-mix-of-redux-state-and-react-local-component-state-ok/
I tend to use redux when the state has to be accessed globally / complex logic that i want to be logged properly

Toggling between React Components toggling with state vs React Router

I was trying to toggle the page with a buttonLink and list elements when I click on the buttonLink. I can basically see 2 popular possible approaches to this:
Using react router and create routes one for the list button and another for the list elements that opens up when clicking on on list button element which gets list elements as props in router
Pass the props to list element but render it in the same page, but with state toggle condition. Example -
this.state.showList===true ? :
Here I'm confused to decide between these 2 approaches. I preferably chose the 2nd approach to toggle between components based on state as I'm less comfortable with Router. But if the number of components in that page increases, it is difficult to maintain it using state value.
But I would like to know that standard approach for medium scale applications.
Any examples or pointers would be helpful, thanks.
I'm using both approaches and distinguish between encapsulated business logic and modifying logic. For example you have persons and relations between those persons. So I have 2 routes <personId>/details and <personId>/relations. With the first you will see person details like name, address, telephone numbers and with the second you see a network of related persons, who are connected with this person. For me I decide between those 2 approaches by what I expect to see after reloading the page (pressing F5). When I'm on the detail page I want to see the details again and also I want to see the relation network again.
But there are some modifying logics like adding a new a new telephone number. Normally you would do this by showing a modal dialog or expanding a form with some inputs and "OK"/"Cancel". When this dialog is opened and doing a page reload I would expect to see the person details again. So I'm implementing this dialog via {this.state.showAddTelephone && ...}
In my opinion just go with react-router. Routes are used in multiple areas of the app. The logic of conditional rendering can introduce too much complexity if it's being used in a lot of places. It would be easier to just take the declarative approach of the router with no logic behind it.

How to structure Redux for a highly de-coupled, plug-n-play complex component?

I'm pretty new to Redux and would like to use it my application but I'm stuck at architecture/design phase for the Redux part. Here are my requirements and my suppositions regarding the design.
Application details:
SPA with AngularJS. Other libs used ng-redux, reselect, rxjs.
Component details:
Re-usable grid component to render huge amounts of data.
My idea:
Create a plug-n-play kind of component-based architecture, where all the internal components of the grid are independent of the parent/composing component like search, sort, row, header, cell.
All the components will have their own set of reducer, action, selector, and slice of state from the store.
Because all the components have their own reducers and can be plugged-in on demand, I need them to be lazily registered to the store instead of being accumulated in one place.
Some of the components like search, sort along with having their own state, also can affect other components state. Ex: setting up of query parameters (searchText, sortOrder etc.) to fetch the grid data which would be handled by another component(s).
My thoughts:
For the 1st point, I'm looking into reselect for supplying the dependent slice of state.
For the 2nd point, I'm still confused about which to use combineReducers/replaceReducer for the lazy registration. I feel combineReducers will not fit if I want access to multiple parts of the state.
For the 3rd point, I'm thinking of following approaches:
a. Passing entire state via getState() wherever required to update multiple parts of the state. Though this approach gives me feeling of improper use of Redux.
b. Component A fires its own action which updates their part of the state, then another action is fired for the other component B to update its slice of state. This approach as well feels like breaking the whole idea of Redux, the concept of side-effect could be used here though I don't know how to use it, maybe redux-saga, redux-thunk etc.
NOTE: Use of either of the approaches shouldn't lead to the component knowing about the other components hence whatever has to be done will be done by passing a generic config object like { actionsToFire: ['UPDATE_B'] }.
I need state management while navigating back and forth between the pages of the application, but I don't require hot-reloading, action-replay, or pre-fetching application state from server-side.
Components will also be responsible to destroy their state when no longer required. And state will have a normalized structure.
I know the requirements might seem weird or not-seen-often but I would keep them that way.
Few things I already know are:
I don't need to use Redux like the classic article from Dan says, but I think I need it here in this case.
I know about the Smart and Dumb components, mostly my components might seem smart (i.e aware of application state) but that is how I want to keep them, I might be wrong.
Diagram of the grid component:
Grid Component Diagram
Redux's global store makes encapsulation and dynamic plug-and-play behavior more difficult, but it is possible. There's actually many existing libraries for per-component-instance state and dynamic registration of reducers. (That said, the libraries I've seen thus far for component management are React libraries - you'd have to study some of those and reimplement things yourself for use with Angular.)

Am I thinking in in react correctly about form behaviour

I'm debating refactoring parts of a site I'm working on from jQuery into react. Before I start I'd appreciate some feedback on my thought process so far.
<DeviceChooser>
<ManufacturerSelect />
<DeviceSelect />
<ButtonOne />
<ButtonTwo />
<DeviceChooser>
That is the desired component. It's behavior is:
The parent (DeviceChooser) gets some json data via ajax on componentWillMount.
It passes part of that data to ManufacturerSelect, which is a select field.
Once something is selected there, DeviceChooser passes some other data to DeviceSelect, which is also a select field.
Once something is selected there, if some conditions are met, both Button1 and Button2 become active
Clicking Button1 or Button2 would redirect the page to a specified url, with parameters set depending on the 2 select fields.
More practically speaking, you choose your phone manufacturer, then in the next select you choose your device from that manufacturer, then you get redirected to either page1 or page2 with some get parameters depending on the button you press.
My questions are:
Who's responsibility should it be to decide whether the buttons should be active? The DeviceChooser or the Buttons?
Who should compose the redirect URL? The Chooser or the Buttons?
I'm going to have variations of this DeviceChooser component all over the website, what can I do to ensure at least some reusability? The caveat being that sometimes it will have more select fields that just 2, and other times different select fields will be part of the equation depending on state (Like, if your device is a laptop, you also specify what shape of edges the device has)
I'm really grateful to any feedback at all. I've also created a Gist with the code I've come up with so far, if it helps.
One of the methodologies that I have followed since getting invested in React is using containers. Containers essentially are components that are responsible for retrieving and manipulating the data and then passing all the relevant data down to all the child "dumb" components that are simply responsible for rendering said data.
Operating under this premise (or something similar) I would suggest doing calculations in the container on the initial data, and pass everything down.
So in this instance we should be do the following in the container (or parent component)
Get JSON data via componentWillMount
Manipulate the data and pass it to ManufacturerSelect
The other questions depend on which framework you're using. Are you able to elaborate on this? Are you using Redux, Flux, ReFlux etc?
I've had a quick look at your code, one super useful thing that I think you should do is specify PropTypes for each component. This helps immensely for debugging, and when you're talking about reusing components in several distinct locations this will be crucial. Also (without understanding the full context) is it necessary to use state everywhere in your components? Would it be possible for them to simply render the props passed down to them? (again this depends a little on the store you'
re using).
It's a relatively generic question, but my line of thinking (quite opinionated) would be as follows:
Your Buttons should become simple, generic Button components that should for this example have the following props (besides perhaps some styling props):
disabled
title
onClick
Your Device Chooser is the one who's got the awareness that components mix together, that these buttons should actually continue to do something after they're clicked, so you'll want to handle that knowledge solely within that component. It glues the rest together (passes data around) and should therefore also make these decisions.
<DeviceChooser>
<ManufacturerSelect data={this.state.manufacturers} />
<DeviceSelect data={this.state.devices} />
<Button
disabled={this.state.selectedManufacturer === null ? true : false}
title='Manufactuer details'
onClick={this.handleManufacturerDetailsClick.bind(this, this.state.selectedManufactuer}}
/>
<Button
disabled={this.state.selectedDevice === null ? true : false}
title='See device details'
onClick={this.handleDeviceDetailClick.bind(this, this.state.selectedDevice }}
/>
<DeviceChooser>
Device chooser's method than can be something like:
handleDeviceDetailClick(device) {
history.pushState('/device/detail/' + device.id);
}
You want to separate your functional components from the stateless ones. A good read for this is http://tylermcginnis.com/functional-components-vs-stateless-functional-components-vs-stateless-components/

Resources