Should React.PureComponent be used for components that are updated frequently? - performance

If a component needs to render several times a second because of a prop change, should this component extend React.PureComponent?
The component has no child components, however, it is itself deeply nested... so the props are travelling through several other components.
In general, what are some key things to consider when deciding if React.PureComponent should be used or not. In which scenarios is it bad to use?

Yes this sounds like a good case for PureComponent because your component is unnecessarily being re-rendered frequently with the same props.
A child component extended from React.Component will call render every time its parent calls render. If instead the child component is extended from PureComponent it will only call render when the parent passes props that don't shallowEqual the previously passed props.
It's generally safe to use PureComponent as long as
your component and its children don't rely on context updates
your component doesn't have object or array props that are directly mutated by its parents (shallowEqual will not detect these changes)

Related

Can react useContext pass value from peer component to peer component(in different file)?

I only see examples of using useContext to pass values between parent and child components. I want to know if useContext can pass values between sibling components, which come from different files.
You can define context on parent component and then use it in its 2 childs respectively siblings.
You can also use Redux for this

Which is best to use Functional component or Class Component

In react project, which is best to use a functional component or a Class component
I believe a functional component is easier to use simply because of the state-management.
Using a class component means that you will have to manage your state as one object. Which quickly becomes messy for large React components.
When using a functional component, states are stored as constants which means that you can access and manage them individually.
In the end its really just about which syntax you prefer.
More information can be found here

Livewire Mount vs. Render

I would like to understand what is the difference between mount and render methods in Livewire components, since I have seen examples where both are used to define initial state of variables. For instance, when you instantiate a variable with records from the model, ¿which is the right place to load the data using the ORM syntax?
The mount() method is what's called a "lifecycle-hook". There are a few more of these kind of methods in Livewire, which are outlined in the official documentation - https://laravel-livewire.com/docs/2.x/lifecycle-hooks - while the render() is the final method that's called to render the actual view.
The mount() method is the construct to the component. This is where you pass in the data that the component needs. This method is only called once, on the initialization of the component, which means its also typically where you set up initial values that aren't constants.
However, since public properties of a Livewire component can only be collections, the instance of a model, arrays or native PHP types like string and integer, you can't pass more "advanced" types that relies on a state - for example like the pagination of a query of models.
That is why you would sometimes need to pass data to the component via the render() method, like you would when returning data in a normal Laravel controller. Another reason to pass data here is that the data is not exposed in JavaScript, like the public properties of the component is.
The render() method is called at the end of every lifecycle request, but before the component dehydrates. Official documentation has more detailed information https://laravel-livewire.com/docs/2.x/rendering-components#render-method - the data defined here isn't a property of the class, and thereby not accessible in the other methods in the component.
So to answer your question, it depends on what type of data you are passing, if the data should be accessible in the other methods in the class or if it's sensitive such that it shouldn't be visible in the JavaScript object attached to the component.
mount method is like any constructor and you can use it in multiple cases, in other you don't need it. For example, if you have a nested component into a full page component, but initially the nested properties are null or require any definition, you define it there. Is used also for the route model binding definitions but you need be clear that any definition you declare here will not be updated, hydrated or suffer any changes after you initialize the component. Mostly, this is the difference with the render method.

How should I add child element to parent object in react reducer

I've got a redux parent object that I'm building based on various api calls and used across components. When I receive new api data, I add a nested object to this parent component.
My current method deepClone's the parent object, adds the new child and then calls a reducer to update the store return { ...state, parent_object: action.value };
This works to an extent although mapStateToProps is not being called when the reducer updates. Also, deepCloning the parent object every time doesn't seem to make sense.
Could someone provide some insight into the proper way to do this.

How to reduce renders using redux + normalizr

I have an app using React + Redux + Normalizr, I would like to know the best practices to reduce the number of renders when something changes on entities.
Right if I change just one entity inside the entities, it will re-render all the components and not only the components that need that specific entity
There are several things you can do to minimize the number of renders in your app, and make updates faster.
Let's look at them from your Redux store down to your React components.
In your Redux store, you can use immutable data structures (for example, Immutable.js). This will make all subsequent optimizations faster, as you'll be able to compare changes by only checking for previous/next state slice equality rather than recursively comparing all props.
In your containers, that is in your top-level components where you inject redux state as props, ask only for the state slices you need, and use the pure option (I assume you're using react-redux) to make sure your container will be re-rendered only if the state slices returned by your mapStateToProps functions have changed.
If you need to compute derived data, that is if you inject in your containers data computed from various state slices, use a memoized function to make sure the computation is not triggered again if the input doesn't change, and to keep object equality with the value the previous call returned. Reselect is a very good library to do that.
In your dumb components use the shouldComponentUpdate lifecycle to avoid a re-render when incoming props do not change. If you do not want to implement this manually, you can use React's PureRenderMixin to check all props for you, or, for example, the pure function from the Recompose library if you need more control. A good use case at this level is rendering a list of items. If your item component implements shouldComponentUpdate only the modified items will be re-rendered. But this shouldn't be a fix-all-problems habit : a good components separation is often preferable in that it makes flow props only to those components which will need them.
As far as Normalizr is concerned, there is nothing more specific to be done.
If in some case (it should be rare) you detect performance problems that are directly related to React's rendering cycles of components, then you should implement the shouldComponentUpdate() method in the involved components (details can be found in React's docs here).
Change-detection in shouldComponentUpdate() will be particularly easy because Redux forces you to implement immutable state:
shouldComponentUpdate(nextProps, nextState) {
return nextProps.dataObject !== this.props.dataObject;
// true when dataObject has become a new object,
// which happens if (and only if) its data has changed,
// thanks to immutability
}

Resources