How to mount/unmount react component instead of show/hide - reactjs

I have a react question.
Basically, I have a component .
class Parent extends Component {
render () {
return (
<Child/>
)
}
}
Notice that the parent is not passing anything to child, rather the child has its own props and state mapped through the redux store. The is basically a modal which shows/hides and its actions are contained by different component. (Show/hide does not resets the state which is what I want every time I open the modal)
Since its not mounting/unmounting I dont have access to componentDidMount every time which I need.
My question is how to mount/unmount rather than show/hide since I dont care about preserving state values. I tried to do
{this.props.showChild && <Child/>}
but that did not work either.
I read about the react reconciliation algorithm just cannot figure out how does it apply here

Related

react native re-rendered components multiple times

In react native, I use some component like audio player, header etc. Also, I use console.log() for debugging for component I put log in start of components :
const MiniPlayer = (props) => {
console.log('Begain Mini Player ....');
return()
}
I got multiple logs, it's re-rendering is happening multiple time without any special event or state change.
app hasn't any issue and not working slow.
Should I control this re-rendering or is it common in react ?
As per your given snippet, MiniPlayer will re-render whenever its parent component re-renders. It's how react works. If a component updates, its entire subtree re-renders regardless whether the children components need it or not. To control it, you can use shouldComponentUpdate in a class component or extend the class with PureComponent, or wrap your component with React.Memo if it's a functional component. Since yours is a functional component, we can make changes to your component so that it re-renders only when its props change as follows.
const MiniPlayer = React.Memo((props) => {
console.log('Begain Mini Player ....');
return()
})
More resources here - shouldComponentUpdate, PureComponent and React.Memo
Also remember that using React.Memo is just going to perform a shallow comparison of props. So even if the values of props are equal but if the reference changes, it would still cause a re-render.
Should you control this re-rendering? Well that depends. If your component is a costly one which performs heavy computations whenever it updates, then you should control this, else it is not going to affect much, as the DOM anyways is going to perform a diff check to determine what is supposed to be updated.

Render two separate components in React App

I am not experienced enough React delevoper yet, so i am having issue with rendering 2 separate components, which are comunicate with each other. So the main task is simple:
user click the button create user form
adding 1 component combination
Btw i want to provide to user the possibility to create as much component combination as he will want. What pattern should i look for? I don't understand how to create two communicating components inside different parent containers.
Here is gif for better understanding
If Main is a component and Sidebar is a component you want to store state in Main and pass props to Sidebar.
Make Main a stateful class based component with a constructor function and store something like this:
this.state = {
addInput: false
}
Then in Main write a click handler. When the user clicks a button set addInput to true.
function addComponent() => {
this.setState({
addInput: !this.state.addInput
})
}
Add an onClick event handler to the button like this:
<input type="button" onClick={this.addComponent()} />
Then inside Main pass props to Sidebar:
<SideBar addInput={this.state.addInput} />
Then inside Sidebar you can use props and a ternary to decide whether or not to display the input section based on whether addInput is true or false.
I wrote this quick and it's a basic rundown. Check out the React props docs for more information.
Instead of using a boolean inside Main's state you could also use a number and dictate how many input boxes show up in Sidebar based on the number value.
Here is an example that I wrote showing another person how to pass props in a React component. Check it out and you'll see an example of passing props to a child component. Look at Parent and Child components and see how props are passed and also state being updated by an onClick event.

Writing optimized React functional components

It is my understanding that the entire React Functional Component gets re-run when re-render is needed or there are any state updates, so how to properly manage the state inside these functions? Is it important to keep it empty of any members like event handlers that you wouldn't want to be re-created every time the function gets re-run?
Is there some sort of best practice for writing optimized functional components?
React Memo is something you might be looking for.
React.memo(...) is a new feature introduced in React v16.6. It works
similiar to React.PureComponent, it helps control functional
components re-renders. React.memo(...) is to functional components
what React.PureComponent is to class components. How do we use
React.memo(…)?
It is very simple. Let’s say we have a functional component, like this:
const Funcomponent = ()=> {
return (
<div>
Hiya!! I am a Funtional component
</div>
)
}
We simply pass the FuncComponent as argument to React.memo function:
const Funcomponent = ()=> {
return (
<div>
Hiya!! I am a Funtional component
</div>
)
}
const MemodFuncComponent = React.memo(FunComponent)
React.memo returned a purified component MemodFuncComponent. This component is what we will render in our JSX markup. Whenever the props and state changes in the component, React will check if the prev state and props and the next props and state are equal if not equal the functional component will re-render if they are equal the functional component will not re-render.
As for second question, yes it's true. You should avoid defining the function inside the render function or in case of functional components, avoid defining inside the function, it will cause unwanted calling of those functions and can result in unwanted behavior as well as cause it to be created every time the component re-renders.
The same goes for adding in-line callback functions for event handlers. They should be defined outside the render function.
As how I get it, You want to know how to manage or improve your react performance right? You are right every Component in react gets re-rendered when there are any state changes in this component or in the parent component (if there is).
So there is a tool (Chrome extension) that helps you finds out which part of the application get re-rendered whenever you make an action React developer tool.

Selective children component render

A basic question I need help here.
Whenever this.setState invoked at parent components, all the children components will be rendered. This will cause the performance issue if I have huge amount of child components.
Lets give an example,
Parent Component
handleToggleTick() {
const newObj = Object.assign({}, this.state, { iconName: ''});
this.setState({
iconName: newObj.iconName,
});
}
render() {
return(
<ChildComponentA iconName={this.state.iconName} toggleTick={() => this.handleToggleTick}></ChildComponentA>
<ChildComponentB></ChildComponentA>
<ChildComponentC></ChildComponentA>
)
}
Based on the example above, whenever handleToggleTick invoked from childcomponentA, setState invoked for new iconName. What I want is, only ChildComponentA only the one get render since props.iconName is related to it, but not for childcomponentB and childcomponentC.
I understand there is an option to check shouldComponentUpdate in childcomponent to prevent it get render. But, imagine I have over 100 of childcomponent, would it be frustrating to write over 100 times of shouldComponentUpdate method?
I need help here, please advice!
React doesn't provide any way to render children selectively. The component will either render or not. But I need to highlight a few points why this is not a problem when we use React in practice.
First of all, you don't need to manually implement shouldComponentUpdate for each component. If you don't want to rerender component if its props and state haven't changed, you can just extend from the PureComponent class instead of the Component class. Note that React.PureComponent's shouldComponentUpdate() only uses shallow comparison for state and props. But this shouldn't be a problem if you follow react best practices and avoid mutating the state.
Also, it's not practical to have more than 100 different components in one render method. React always encourages decomposing your UI into smaller components and using component composition. When we follow this approach, components will be nested inside each other in different levels instead of having a large number of components in one render method.
What I'm trying to explain is it's more practical and easy to manage when we compose our component in a nested fashion (2) rather than having lots of components inside a big container component (1).
In your example, if ChildComponentB and ChildComponentC are inside another component called ChildConatainerComponent then we only need to implement shouldComponentUpdate() for ChildConatainerComponent. Then it will automatically stop rendering any child element inside it.
render() {
return(
<ChildComponentA iconName={this.state.iconName}
toggleTick={() => this.handleToggleTick}/>
<ChildConatainerComponent/>
)
}
class ChildConatainerComponent extends PureComponent {
render() {
return (
<div>
<ChildComponentB/>
<ChildComponentC/>
</div>
);
}
}
Another very import concept to keep in mind is calling render function doesn't mean that React recreates all the DOM elements again. The render method only make changes to React virtual DOM which is an in-memory representation of DOM and it's faster than actual DOM. Then React compare versions of virtual DOM which are before the update and after the update and the actual DOM will be updated with only what has actually changed.
Another solution you could consider is moving iconName into ChildComponentA, considering this is the only component related to it.

How do I manage state on a React component that can have state changed from the parent or from events upon it?

I'm trying to make a custom checkbox component (a three-state, actually, but that's irrelevant except to say that I'm not just using an INPUT), and I'm not sure how I can make it able to change "checkedness" from clicks on itself and from a value-set coming down from the parent.
Currently, I have it working as a self-sufficient component that takes an onChange prop with the handler callback that it calls to send the value the parent component after clicks. It uses a state to store the checkedness, which is referenced by the display.
If it were merely a display of checkedness, with value being managed from outside, I'd use props, naturally. If it were only a self-sufficient checkbox component that took an initial value then only responded to clicks, I'd use state, like I am, but my problem is that I want it to be clickable to turn itself on and off, and allow the parent to turn it on and off as well.
I'm a beginner to React and the "React way of thinking" so I suspect I'm just approaching this wrong. I kind of get the impression that the proper way to do this would be for it to be a display-only component that passed clicks up to the parent to deal with, and in turn received props updates for value changes down from the parent, but that would make the component far less reusable, to my mind.
So how would I go about making a checkbox change from both internal and parent sources?
Relevant links are welcome, as well.
You may treat the checkbox as a dumb component, which means that it doesn't hold any internal states, but only receives data from outside via props and then render them. You can see the detailed definition of dumb components here.
Meanwhile, when the checkbox is clicked, such event will be handled by the component's parent, or event ancestors, this is called inverse data flow, which is described in Facebook's Thinking in React blog post.
Moreover, to decide which component should hold certain states, I find the following guidelines very useful:
Remember: React is all about one-way data flow down the component hierarchy. It may not be immediately clear which component should own what state. This is often the most challenging part for newcomers to understand, so follow these steps to figure it out:
For each piece of state in your application:
Identify every component that renders something based on that state.
Find a common owner component (a single component above all the components that need the state in the hierarchy).
Either the common owner or another component higher up in the hierarchy should own the state.
If you can't find a component where it makes sense to own the state, create a new component simply for holding the state and add it somewhere in the hierarchy above the common owner component.
The pseudo-code snippet:
const Checkbox = React.createClass({
// Propagate the event to parents
onClick(evt) {
if (this.props.handleClick) {
this.props.handleClick({checked: evt.target.value});
}
},
render() {
return (
this.props.checked ?
<Input onClick={this.onClick} type="checkbox" label="Checkbox" checked></Input> :
<Input onClick={this.onClick} type="checkbox" label="Checkbox"></Input>
);
}
});
const Container = React.createClass({
handleClick(evt) {
// Change the container's state, which eventually changes the checkbox's view via props.
this.setState({checked: evt.checked});
},
render() {
return (
<div><Checkbox checked={this.state.checked} handleClick={this.handleClick}></Checkbox></div>
);
}
});
You change it from only the parent.
class ParentComponent extends React.Component{
handleChildCheck(){
this.setState({
childChecked: !this.state.childChecked
})
}
render(){
return(
<ChildComponent checked={this.state.childChecked} handleCheck={this.handleChildCheck.bind(this)} />
)
}
}
Now if you wish to control the checked state from the <ChildComponent/> just call this.props.handleCheck() from the <ChildComponent/>
This way the controls will always be available within the <ChildComponent/> via this.props.handleCheck() within the <ParentComponent/> via this.handleChildCheck().

Resources