What effect do multiple state components have on react app? - reactjs

According to the docs, one should avoid having multiple components with state. I am in the situation where I want to make a text box that automatically expands vertically as the user writes, and for that I'm using this trick http://www.impressivewebs.com/textarea-auto-resize/, which means I need to get the height of a component. Now, I've been playing around with it a bit, and it doesn't seem feasible to pass a ref to my parent component which contains state, so the easy way out would be to keep a piece of state in the component with the textbox, and then use the ref from there.
This got me thinking, how exactly do multiple state components negatively affect my app? Is it only maintainability / comprehensability? Or are there actual performance issues with it? I've noticed a lot of open source react components that you would just plug in to your app keep state, meaning if you use open source components, chances are you will have several state components in your app.

It's totally ok to use local state for this kind of tricks on DOM. It's even better approach, than to share such implementation details to parent components.
In general, use this places for state:
Application-wide data in stores outside React (redux, flux-store, observables)
Form temporary data can be placed in store also. But if don't need it anywhere else except form, it's better to place this data in form component.
Tricks on DOM, short living and very local state can be placed in component that just need it
are there actual performance issues with it?
No. If you'll place all your state in components, your application will become even faster. Because when you update local state, only this component and it's childs updates.
But you shouldn't do that, because it kills maintainability.
lot of open source react components that you would just plug in to your app keep state
If component doesn't allow you to control it through the props - it's bad component. Usually open source components written to be easier to use, so they provide nice defaults, that allow you to just place component to your application, and be happy with that.
For example, Tabs component usually controlls selected tab using local state. But also it takes selectedTab and callback onSelect, so you can control it by yourself.

Stupid components (like your textarea component) should not have state with data. But they can have their own UI state.
In this case you can easily keep textarea height in state of stupid component.

Related

Hook re-render whole page on single change in a sub component

I create 2 Text Boxes one with hook and the another one with the old style, now in Hook mode when the user input change the textbox value the whole page rendered, but with old style there only the text-box rendered not the whole page, if you have the complex page with many objects like (Data Table, form, buttons, inputs, etc..) the single change on one of these components forced to re-render everything and it decease performance, for example typing in the text-box take time to effect on page and the delay time is more than user typing speed.
the one workaround solution is using the callbacks and useMem but if the page is complex(lots of objects as described, and all of these objects has many properties the callback and useMem is very very complicated to handle single object property.
SandBox Example
This is exactly how react hooks should work. what will cause a rerender in react? two things:
change in props
change in hooks or say in a better way hooks state
in the second case, the useInput state is changing so that causes a rerender and it's absolutely normal behavior. I think using custom hook in that way is not a good practice.
I recommend reading this article for more information on react rendering: https://www.codebeast.dev/usestate-vs-useref-re-render-or-not/

MultiStep React Form

What is the best practice to implement a multi step form?
I know that there are several different practices, but which one is the best/most performant ?
Redux/Global state management: Easiest but bad for performance, because it will check every connected component on every key hit.
Raised State: Have a parent component keeping all state, but this couples the components too close together and makes the parent component too complex
Render props: The child components render the next button of the form as a render prop and push their data to the parent on next click => this makes the parent complex as well and it may be difficult to pass the data to the parent.
What are your thoughts? Thanks in advance!!
I would go for the second option, because it keeps the children simple and dumb (MVC).
The parent component keeps track of all data and which form is currently displayed, which keeps all logic within one component (which makes it easy to update).
Performance won't be a problem, because it only displays one form anyway, so the performance is the same as if using a single form.

Communication between nested but independent components in react.js

i like to develop a simple tooltip component in react.js
the tooltip gets defined like so in e.g. App.jsx:
<TooltipLink>Hover over me
<Tooltip>I am the Tooltip content</Tooltip>
</TooltipLink>
My question is: What is the best way of TooltipLink and Tooltip to talk to each other?
They are nested but I cannot use props because they are not nested directly in the component itself. Also, I don't want to use the parent (e.g. App.jsx) to manage the communication between TooltipLink and Tooltip because I want them to be self-contained.
I thought about refs but when i define a ref inside the Tooltip component then TooltipLink does not know about it (I assume because refs only work when components are nested inside the components themselves).
I could of course use simple DOM-programming for TooltipLink and Tooltip to communicate (e.g. use e.target when the user hovers over TooltipLink and then find its first child) but I thought there must be a more react-y way...
You have 3 options:
cascading props in the whole hierarchy
using redux
using the context API
I prefer to use redux, because the context API is not officially supported (breaking changes may happen, like in react 16.3). Cascading props is not really beautiful but may be convenient for small apps. (<MyComponent {...props}>)

React Redux Components Communication Pattern

I am looking for a good code pattern to allow some communication between components, when using React & Redux.
Most likely this communication should be done via redux, like many articles suggest. (like this one, for example).
However, there are some situations when using the store would be a bit of a hack rather then using it for state management. These special cases are usually when you need to give a command to a component, like show or hide.
I will give an example:
Lets say that we have a <Tooltip /> component which all it does is render some help icon, that when clicked, opens a tooltip popup.
And lets say that we have more than one in a page, but we want to make sure that only one is open at a given time. So if tooltip A is open, and the user clicks on tooltip B, then B should open and A should close.
Here are some patterns that I thought might be relevant to implement this requirement:
Using Redux: We could have in the store some state for these tooltips:
{
showTooltip: "A" // the ID of the tooltip to show
}
This means that we have to connect the tooltips to the redux store, and check for each tooltip if it's ID is the one that should be opened, and when the user clicks on the tooltip icon, we dispatch an action to set the opened tooltip.
Using additional event mechanism: We can use an additional event mechanism to Redux, like emitter.
In this case we can fire an event whenever a tooltip is about to be opened, and all other tooltips can listen and hide themselves once they get such an event.
I have to say that it seems to me that maybe having two event mechanisms in the app seems a bit redundant, but on the other hand, using redux store to communicate with components seems a bit overkill.
Would love to hear some opinions about this issue.
The React and Redux world generally encourages representing your app's behavior as state. For example, rather than an imperative $("#someModal").show() command, you might save a flag value somewhere that says {modalVisible : true}.
There's numerous examples of using state to drive modals and popups. A typical implementation would store the values for a single modal or a list of modals in state somewhere (either in a parent component or in Redux), and then render modal components as appropriate based on those values, such as: {type : "notificationPopup", level : "warning", message : "Something happened!"}. The basic approach works whether you're storing the data in React, Redux, MobX, or something else.
For specific examples, see Dan Abramov's answer to "How can I display a modal dialog in Redux?", Dave Ceddia's article "Modal Dialogs in React", the article "Scalable Modals with React and Redux". I also have other articles that demonstrate modal management in the React Component Patterns#Modal Dialogs and Redux Techniques#UI and Widget Implementations sections of my React/Redux links list.

How to pass prop to sibling in React?

I've designed a pretty simple responsive layout (be sure to open link with Chrome) and now I'm trying to implement it in React. I've attached some screenshots of the layout as well.
This app is supposed to be the typical tab/nav app, but due to the responsive layout, the view hierarchy is pretty awkward to work with in React.
I've built a React component called Layout to abstract away all the layout stuff. Layout also has props for renderLeft, renderRight, title, and onTab. Layout's children are then rendered into the content block.
The easy solution would be to make Layout a child of the current view and render whatever you want. However, this is going to mess up some animations I had in mind. I want to have a CSSTransitionGroup element wrapped around the tabbar, the title, and the left and right buttons animating them as they change. Thus, the Layout element must remain the same between the views else a new CSSTransitionGroup element will be rendered for each view which isn't good.
So now the problem is that I have a Layout component with a view rendered as its child (but sort of as sibling with respect to the App component), but the view needs to specify renderLeft, renderRight and title for the Layout which is its parent! For example, in the top-level App component, the render function may look like the following, and I need some way of setting Layout's renderLeft from the View.
render() {
return (
<Layout renderLeft={??}>
<View setRenderLeft={??}/>
<Layout/>
)
}
The only thing I've thought of so far seems totally like the wrong way of doing it:
In the top-level App component, have a state variables for renderLeft, renderRight, and title and App passes those to the Layout props. Now for the view, pass some functions like setRenderLeft, setRenderRight, and setTitle which will change the App state and thus change the Layout. We can thus call these functions in componentWillMount for each view.
This just seems like a total hack and seems to break the whole idea of one-directional-data-flow. However, I'm not sure how else to do it! Are there any more proper ways of doing this? I'm reminded of the concept of delegation when building iOS apps, but thats very OOP and not very FP.
Any ideas?
Your question is a little difficult to tell exactly what the issue is, however if I were you I would read up on https://facebook.github.io/react/tips/communicate-between-components.html
For communication between two components that don't have a
parent-child relationship, you can set up your own global event
system. Subscribe to events in componentDidMount(), unsubscribe in
componentWillUnmount(), and call setState() when you receive an event.
Flux pattern is one of the possible ways to arrange this.
You want to either have the siblings talk to the parent and communicate there, or at the global level.
Hope this helps.

Resources