React Design Pattern with multiple Components - reactjs

I'm trying to get into react for some days now but I have problems to get the design of my application clear.
What I want is to create a "complex" form which communicates with an API. Behind the API there is a classic SQL DB.
So say I have a Videoplayer which has a m2m to a Playlist-Table.
In React I have now a component with all the fields of the player. The list field in the player table shows the possible selection of playlists (i get this data via API). So far so good.
Now I wanted to create a new component with a from for the Playlist stuff if someone wants to create also a new Playlist when creating a player (there is a button to click for adding a new playlist).
Now my questions:
Because the Playlist form needs to do a POST API call and should return the newly created id to the player form component... Should the Playlist component have its own state?
Is it recommended that the two components have their own state? (there are some more m2m fields in the player form and with just one state the state gets quickly hard to keep structured (also because react discourages it to have a nested state structure.
Is it recommended to unmount the player form component when adding the new playlist or make the player form just invisible?

I would take a look at this
What follows is my opinion. There are a lot of different approaches to these types of things, but this is what has worked best for me.
Instead of giving your child component it's own state, make all your view components stateless and wrap them in a large container component. Then
1) You playlist form can recieve the post API function as a callback. In your stateful container, define it as something like
apiPost(){
apiFunctionCall()
.then(result){
this.setState({ data: result })
}
}
Then you can pass that data wherever you need to, because all your components are children of the component containing that data in state so they are all elegible to receive it as props. You can repeat this pattern with any of your components, so it's very helpful if you need to share data between components, especially the results of api call. Also don't forget to bind any functions that set state!
2) I'm a bit unclear as to what you mean here. Are these components siblings or descendants? If they are identical siblings (i.e. multiple instances of the same thing) then if you need to, move them to a separate file and define them as their own stateful react components. I generally find that with the pattern described above this is rarely necessary, and your state can be managed in one place. If you clarify on this or post some code I might be able to help more.
3) I would unmount it and I would do it with some nifty inline logic. Have a variable in state maybe displayComponent: true. When you want the component to be hidden, set that to false and set it to true when you want it to be seen. Then in your render statement it's as easy as:
{this.state.displayComponent &&
<Component />}
Now everytime React renders the dom, your component will only display if that variable is set to true.
Hope this helped! I highly encourage you to read the article I linked above and explore this design pattern a bit more. It has helped me immensely in my React development.

Related

What is proper or effective way for Composition of React Component?

I have multiple view in my application, I need helpl in how to use reusable component effectively ? Is it ohk if I create viewspecific component from reusable component ? - Generic Tree View . For users View which will render with user specific data and actions .
I have written re useable component in my react app.Which I have to use it with different data and action is it ohk to creat new component which use resuable component and provide data related to that ?
i.e
Component - DepartmentTree which renders and some functions related to Department. So finaly I will render
Component - usersTree same way here it calls and methods related to users . In the users view I will render
It's definitely OK to create a view-specific component that renders a reusable component. You could let this depend on how big your page is. If it includes a lot of components, then do split them up in view specific components.
About the data, you have a few options... First of all you could map the data response to a general structure that your TreeView component can read, so you only need to pass some props to the TreeView component. You could do this in the redux reducer.
If you require specific data different behaviour, but you still want to use the reusable TreeView component, you could think about creating a Higher Order Component. This component will wrap your reusable component and add some specific logic to it. You can read about it and see some good examples here: https://reactjs.org/docs/higher-order-components.html
The most important thing I always keep in mind: It's not always about how you finally do it, it's about keeping it simple, understandable and consistent.

state vs props for scenario with separate view and data model

I'm building an application where I would like to provide separate views for same data.
In my current implementation, data is obtained by web service call and persisted in state of App component in App.js. App component hosts (renders) another component called StackEditor, which acts as a view for this.state.components in App component.
UI elements rendered by StackEditor can be moved around, and to synchronize state of App I do it as below:
<StackEditor
components={this.state.components}
onLocationChanged={this.handleLocationChanged} />
In handleLocationChanged I update the state:
handleLocationChanged(e, data) {
this.setState(prevState => {
// event data copied to state here
return {components: prevState.components};
});
}
As state is now updated, this forces StackEditor to be rendered again, as its property components is bound to state as components={this.state.components} (see in the code snippet above).
This all works, but now I started questioning if I'm doing it right.
Q1: Should I be using state instead of props?
It seems that location of component is mutated in principle, although from StackEditor point of view, it is immutable (I can decide that change is invalid and not to update the state in event listener).
Q2: Is it possible to share part of the state between 2 components in React?
If I somehow convert StackEditor from getting components from state instead of props, will I get notification on state changed by child component (StackEditor) in my parent component (App)?
Q3: Also, are props more convenient to use than state in general?
When I created another component following HOC guidelines (https://reactjs.org/docs/higher-order-components.html) I discovered that props are easily forwarded to "wrapped" component, but not state. If I provide a function to call back via property (as I did above), "wrapped" component can easily call it, without even noticing that it's "wrapped". I don't see how I can easily notify "wrapped" component about state change in "wrapper", without writing some extra code.
If you imagine your application to be a tree of components in a well designed app it's usually like this:
the leafs are stateless components . They decide how data is rendered.
the nodes are stateful components. They decide which components and data to render.
Q1: Should I be using state instead of props?
It depends on which category of components you have (node or leaf).
Q2: Is it possible to share part of the state between 2 components in
React?
If you feel that your app has a lot of state that mutates and needs to be used by several components spread over your tree you usually start to introduce an external state management library (e.g. redux). Components can subscribe to your store and become stateless as your store now handles the state.
Q3: Also, are props more convenient to use than state in general?
They solve different problems so you can't really say that. A stateless component is usually easier to understand but has no capabilities to control anything.
Also read Identify where your state should live and When to use redux.
All that is only a rule of thumb. A lot of the time you will have components that have both state and props because they control parts of your app but delegate other parts to their children.
This all works, but now I started questioning if I'm doing it right.
As far as I can see from the code you provided this looks pretty much as it has to.

React state vs. Redux state (real usecase)

I have read multiple tutorials how to make CRUD in React with Redux bot none of the authors explained why they are using Redux. (Like they are only using it for fancyness or because all other are using it.)
Citate from here:
People often choose Redux before they need it.
Through further researching i learned that Redux is good for:
Share state between components
Let some data be accessable in the entire application
It does not exist a wrong or right. But only the do what makes sense.
My usecase
I have a component that uses a shared component:
¦-- domains/FooManagement/Components/Editor.jsx <-- Most-parent of the editor
¦-- domains/FooManagement/Components/..the children of Editor.jsx
¦-- shared/Components/Tabs/Tabs.jsx <-- Most-parent of the tabs
¦-- shared/Components/Tabs/..the children of Tabs.jsx
Tabs.jsx is used in Editor.jsx.
Which is the right approach?
Approach 1: React state (I think its the right one)
Every dynamic rendering that can happen is stored in the state of Editor.jsx.
onClick on a tab (nested shared component) calls a callback written in Editor.jsx that updates the state in Editor.jsx. This state change then rerenders the new active tab
That means that on every other component like Editor.jsx that uses the same nested Tabs.jsx, the changes for the tabs must be handled in the editor.
Code example:
/**
* domains/FooManagement/Components/Editor.jsx
* or
* domains/BarManagement/Components/Editor.jsx
*/
onTabChange(activeTab) {
this.state.activeTab = activeTab;
this.setState(this.state);
}
I think this is the right approach because:
I dont need the state of the editor or the tabs component in the entire application. But only on this view one time. Like the short term duration definition.
Approach 2: Redux state
Editor.jsx has its own state
Tabs.jsx has its own state
States are stored in Redux
Editor.jsx dont passes data down to Tabs.jsx because Tabs.jsx takes the data from the Redux store
Benefit:
The code example above must not be in Editor.jsx because its not the editor's interests how the tabs component behaves. (Or should the editor interests?)
I think this is bad because
Its too much magic in here. Immagine there comes more components in the editor like sortables, tables, etc. In the Editor.jsx you will not see what can render your view. It is hidden in the other components.
But if its all handled in Editor.jsx, you have the overview and the control of all what must be rendered on any change.
What is the right approach for you?
speaking of real usecases, I'm working on an everyday growing project, at first, pure React state management seemed like a very convenient way to develop, and it was working just fine when the components structures were still somehow flattened, but as we go along it, the project gets more complicated and by complicated I mean, more component become nested, and one parent has a serie of nested children, so we have to pass props all the way from the parent to the most furthest child, and whenever we need to rerender the parent, all the children have to go through this cycle also, as for your case, if you know that your project won't get way more complicated, and Tabs.jsx won't have maybe something like form that contains further nested subForm that contains a Grid maybe, you surely don't need to complicate your life with Redux, but as I stated earlier, for us we started to notice that at this stage, integrating Redux would be considerable

Reactjs - How to make components aware of the current view state?

Tools I'm Using: Reactjs 0.14.7, react-router 2.0.0 (Flux Pattern)
Note: I tagged Redux, just cause I got a hunch(I haven't used it) that what I'm experiencing might be one of the reasons people rave about it.
I understand that react-router already manages which parts of the
component tree are currently in view and renders the components based on the state of the current view tree.
Question:
But what if, based on the components in view, one component needs to know what other components are also in view and behave differently depending on what other components are in view(the view state)? What strategy would you suggest to allow components to be aware of the other components in view?
My Current Solution:
I currently am trying to use the URL to infer this global state, and even parsing it and putting it into a store in order for components to be aware of the view state by listening to changes from that store.
My Issue With This Solution:
In a nutshell managing that view state with a store becomes a highly entangled process with extra actions sprinkled all over the code.
1) Actions must be called for any user event that change the route.
2) Action need to be fired when navigating outside of components(I think its much cleaner to keep action firing in components(feel free to debate that one).
3) You must also consider the back button(currently using react-router onEnterHooks to catch when that happens).
Yet I really like the concept of encapsulating the view state because I can imagine that it creates a nice mental model and also smarter components, but just parsing the current URL and using a utility file to determine the current view state when needed, seems like a much easier/cleaner solution to manage then a store that contains the current view state.
Components should never need to know what other components are being rendered, that's one of the fundamental concepts of React. You're trying to extract the "view state" from your component tree, when your component tree should be determined by your state. If you're already using Flux, you need to keep that information in the store, where it will be made accessible to any component that subscribes.
Flux isn't about making development easier or faster for an individual, it's about enabling practices that make it easier to keep a mental model of what an application is doing. This might come at the expense of some simplicity.
Redux is a refinement of Flux that combines the multiple stores that can be subscribed to individually with a single large state tree, with different parts of the tree created by different "reducers" -- functions that take a state and an action and return a new state. It is exactly "a store that contains the current view state." What you describe is also a pretty good description of the type of development common in hacked together jQuery applications, the type of development React seeks to avoid.
I think the core of your misunderstanding falls into how React component's should be layered. It's a tricky topic, and re-aligning your thought process to accurately understand what is a state vs. prop in your model, is a unique challenge.
But the solution to this problem you are facing is simply to order your components more 'correctly'.
At a high level, each component should only care about the props that are passed to it, and not about anything else whatsoever. However, which props are passed are determined by it's parent Component. As a result, that parent can make those decisions, which then have an end result in the child.
As a simple but practical example;
var Parent = React.createClass({
funcA: function(){
this.setState({propB: 'something new!'});
},
render: function(){
return (
<div>
<ChildA propA={this.state.propA} funcA={this.funcA} />
<ChildB propB={this.state.propB} />
</div>
);
}
});
With this layout of concerns, ChildA is capable of handling user input, passing it to funcA which then impacts ChildB. But all of this happens without the Child components knowing anything about one another whatsoever.

Can someone give an example of an app that is extremely well suited to Flux/Redux?

If the example could help me understand the answers to the following questions I would be very happy:
Should you use a Flux/Redux store for data that is unlikely to change throughout the apps lifecycle? And if most of the data in your app is like this should you even bother to use a flux/redux store?
I ask the question in the title because the vast majority of apps seem to be of a similar kind to mine (be it more complex) as described below. I somehow see Redux as a framework designed for apps with internal data that gets mutated (hence the large abundance of counter examples in Redux tutorials).
In my case, the first screen of my app will prompt the user to select a hotel from a list. Once selected a menu structure specific to the selected hotel will appear (which is amazingly easy with react), created from an api response to the server. Once a hotel is chosen it is unlikely that it will be changed, but possible, in which case a totally new set of menus will be loaded. The rest of the app will simply be pushing data to the server by means of form submission. And receipt confirmation for the user from the server.
Suppose you have a component tree that looks like this. Component A is the root. There's a button in Component G.
Component A --> Component B --> Component C --> Component D --> Component E --> Component F --> Component G
Now, let's say you have another component, Component K, which is nested as follows:
Component A --> Component H --> Component I --> Component J --> Component K
Component K is a simple view that takes in a prop and renders a span tag with the value of that prop. Component G contains a button that, when clicked, changes the value of the prop that Component K renders.
Now, the React-without-Flux way to do this would be to have Component A own the state and pass it down as a prop to Component K. Component A also would have a method that modifies that state and passes a reference to that function as a prop all the way down to Component G.
That doesn't sound so bad if you do it just once, but what if you have dozens of state variables? What if your components become even more nested? Your controller-views become very difficult to manage, and you will be passing dozens of props to intermediate components that won't even use those props (only pass them down to their children).
Flux allows you to reduce the complexity of your controller-views. Your controller functions can be placed in separate modules, which can be imported into the components that need to use them. Components that need to access state can subscribe to the store that contains that state.
As far as I'm concerned, this is the primary reason to use a Flux pattern.

Resources