How to handle layout containers which do not match component hierarchy? - reactjs

As far as I've understood, in React, components should communicate in an hierarchical order through the nested hierarchy. Given this, how should it be handled when an application's layout container structure don't match the natural/expected/logical component hierarchy.
As an example of my question, I've come up with a scenario based on my app, that I'm not sure how to implement properly:
The screen is split vertically in two halves. This is done having two
div containers side by side. To each halve there's a corresponding
component: ItemsList and ItemDetails.
Nested inside ItemsList, there are several Item components we can
click on.
Each time there is click on an Item, the corresponding defined _itemID prop value needs to be sent to ItemDetails so it can load and display Item details in there.
The problem is, given the component structure, how can ItemDetails be a child of Item and still be on the right section of the screen where it's intended to be. (At least without some weird CSS which I want to avoid).
Here's the layout:
<div className="wrapper">
<div className="itemList" style="width:50%; display:inline-block;">
<div className="item">item1</div>
<div className="item">item1</div>
<div className="item">item1</div>
</div>
<div className="itemDetails" style="width:50%; display:inline-block;">
The details of the selected item.
</div>
</div>
I believe I could send information from a child to parent following up the hierarchy, but this don't seem practical. Considering this scenario is just a simplification of my actual problem (I have a lot more nested components), I believe this would make the code messy and confuse.
Is there a clean, simple way to achieve this in React? Am I missing some concept?

If it were me I would have a container component based off your wrapper. It would handle all state changes and be the source of truth for what the currently selected item is. Then you'd just need to pass a callback from the wrapper component through props down to your ItemsList that would handle setting the state of the active item.
Then you can just pass activeItem as a prop to the itemDetails component. It is a fairly common pattern to have a container component that manages state and passes callback functions down to child components that would allow them to create an action that changes the state of the container
The heirarchy would look like:
<Wrapper> // holds the state of active item and provides functions to change the active item
<ItemList /> // provides a list of items that when clicked sets active
<ItemDetail /> // shows the detail of the currently select item
</Wrapper>
Here is a pen of what i'm trying to explain
http://codepen.io/finalfreq/pen/KgEzgE

This always depends on many things. If you intend for a small project you are fine working with setState and refer to finalfreq's great answer. If you intend to scale well (aka grow without pain) then I would opt for a state management library.
I hate to be the guy who answers a simple question with "Use ... library! It's awesome!", and like I said, it really does not get much better than finalFreq's answer if you don't have the need to grow your app. A redux author even mentions that you should learn react without redux first, and you should not reach for it until you have a real need.
If you use redux then you should never have to worry about component structure for the sake of passing scope. Component structure if I am not mistaken(which I often am XD) should be based on what is easiest to understand and maintain, also performance comes to mind.
Your question is in the context of react, but I think this is really a state management and data communication question. I opt for redux.js lately(a pub/sub like library), but there are many alternatives. Redux requires a bit more typing, but offers extreme explicitness that you may appreciate as the project grows.
But the main reason I would reach for this is that it focuses on functional programming principles, and pushes your state mutations to the outer fringes of your app. This simplifies your code. If there is a bug it's easy to find(All mutations should be in the reducer files. You would also move your calculations to a util file which simplifies your code even more)
http://redux.js.org/

Related

Create React Component that looks similar to existing Component

I have a Card component. I want to create a Component that is similar in appearance with small differences.
it will likely have additional/ different functionality (event handlers etc)
What is the best way to architect this? Do i just create a new component or are there better strategies?
Thanks
Think of the component itself as a blueprint (I hesitate using "class" here because JavaScript). When you mount the component inside your render function, or in the case of functional components your returned component, you are "instantiating" that blueprint/class.
So for your example, you have a <Card onPress={someEventHandler} style={somestyle}/>.
You want another <Card /> component with different style and handler? Just instantiate it again:
<Card onPress={someOtherEventHandler} style={someOtherStyle} />
Maybe you want another <Card /> component with same style, but different handler? Easy:
<Card onPress={someOtherEventHandler} style={someStyle} />
Similar to instantiating objects in standard OOP, there is no right or wrong answer to this. If you need a card for each element in an array, use a map:
{someArrayOfCards.map(card => <Card onPress={someEventHandler} style={someStyle}/>)}
Hope that answers your question.
EDIT: Another important thing to understand is that each component represents a node on the VDOM/DOM. The reason it actually doesn't matter which architecture is used to instantiate each component is because you're creating a separate node regardless.
If they are very minor differences, pass a prop into the Card Component, and have an if statement in there that results in different functionality.
However, if the functionality is different (different state, events etc), then duplicating the component and changing it can often be the cleaner solution.
As ever with deciding on architecture, both are valid, and it really depends on how large the differences are, and how (in the future) each of the components are likely to change.

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

React Design Pattern with multiple Components

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.

ReactJS: Why use this.props.children?

I've realised that none of the components I write use {this.props.children}.
I tend to compose my components the way the official docs state at the top of https://facebook.github.io/react/docs/multiple-components.html.
Is nesting the components like this...
<A>
<B />
<C />
</A>
...beneficial over composing them like this?:
A.js
render() {
<B />
<C />
}
Presuming that's the right terminology, what am I missing?
In my applications I rarely use this.props.children, because I often know specifically what children I want to render. In libraries, or components written to be re-used outside of a specific component hierarchy, I've seen it often. I think this.props.children has more relevance to that use-case.
Edit: I thought I'd elaborate on some cases that this.props.children can come in handy. One such example is when creating components which follow the 'render prop' pattern. i.e. I've got some components that require pulling data in from multiple 'render prop' HoC's, such as an Apollo Query component as well as a state management HoC. I combined all my different data sources into one HoC and then called children as a function, passing in the result of pulling out all the data I needed. That being said these days I prefer and look forward to wider adoption of Hooks as an alternative to render props.
Really any component which you want to render arbitrary children; another example I've used props.children is when creating a HoC that required a user be authenticated before rendering the child, redirecting to a login screen when the user isn't logged in. I could wrap any of my 'protected' screen components with this auth HoC.
It's still something the majority of my components don't use, but just another tool to be applied when the situation warrants.
I'd say it would be useful when you don't know what you want to render.
For instance, you have a tooltip wrapper, let's say it's A component in your scenario, and you can use it to pass different content:
<A>
<div>Some text...</div>
<ImageComponent /> // render an image as well
</A>
Or:
<A>
<div>Only text</div>
</A>
Some components don't know their children ahead of time. This is especially common for components like Sidebar or Dialog that represent generic "boxes".
We recommend that such components use the special children prop to pass children elements directly into their output:
Read More...
Children is a special prop that can be passed from the owners to the components defined inside their render method. It allows us to customize a structure of a component.
With props, a child component keeps its structure under the full control and only certain attributes or values are allowed to be passed. The structure of the component is hard coded.
In the React documentation, children property is described as opaque, because it is a property that does not tell anything about the value it contains. As a result it allows a client/parent to customize a structure.
We can also say, that the components defines only a kind of basic template/structure, for instance by providing a kind of "header". And the consumer reuses this header structure, by adding children.

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.

Resources