redux causing component re-rendering - redux

I have a component which is connected to global store and getting some data from the global store. from some portion of this data is sent to another component via props and inside that component i have generated required jsx based on data. Also inside the child component mapdispatchtoprops is also used and it is also connected to global store as well.
The problem case scenario is child component re-renders depends upon the global store data.
The key for global store is like -
foods : {
'list' : '',
's' : '',
fetching : 0,
slist : '',
category : '',
cproducts : ''
}
I guess what happening is the child component is re-rendered 7 times because the number of keys inside global store for foods is 7. if anyone is interested he/she can share his/her views

Components have a render method which returns the JSX markup that it renders to the DOM. For change detection, React use a local state, which is only local to a component, when the state changes the component and its children are re-rendered to update the UI of the changed state.
A quote from the React documentation:
These components must not retain internal state, do not have backing instances, and do not have the component lifecycle methods. They are pure functional transforms of their input, with zero boilerplate. However, you may still specify .propTypes and .defaultProps by setting them as properties on the function, just as you would set them on an ES6 class.
PURE COMPONENT is one of the most significant ways to optimize React applications. The usage of Pure Component gives a considerable increase in performance because it reduces the number of render operation in the application.
So change your app to be like this
import React, {PureComponent} from 'react';
class Sample extends PureComponent {
render() {
return (
<div>your structure here</div>
)
}
}
export default Sample;
Please read more on react PureComponent. here

Related

Handling unexpected mutations properties in Vue3js

I have a vue3 webapp that I use to edit some multi-pages documents.
All the pages are stored in a state with pinia. My pinia state is an object with a pages property that is an array containing all the data of each page.
Each page of each document use a specific template, so I created multiple components to handle each template, and I also have subcomponents for some parts that can be found across multiple templates.
I loop through the pages with a root component, passing a reference to the page object, like it :
<PageWrapper v-for="page in pages" :key="page.id" :page="page" />
Then, inside the PageWrapper component, I use the according page template's component, passing along a reference to the page object (the same with subcomponents if any) :
<PageFirst v-if="props.page.type === 'first'" :page="props.page" />
<PageServices v-if="props.page.type === 'services'" :page="props.page" />
<PageTotal v-if="props.page.type === 'total'" :page="props.page" />
<PageContent v-if="props.page.type === 'content'" :page="props.page" />
I wonder what would be the best way to edit a property of my page object from a subcomponent, as I know that it is a bad practice to mutate the property directly.
Do I have to use events ? Is PageWrapper the good place to catch all the events and the modifications?
Any advice on this matter would be of great help to me.
Thanks a lot for your help!
As the Vue official document point out:
In most cases, the child should emit an event to let the parent perform the mutation.
So the answer is you should let the parent do the job of mutating the props. And it will never be a bad solution.
But, look at your design. Your parent component PageWrapper works just like a wrapper. It does nothing but a container for its child.
The props one-way data flow prevents child components from accidentally mutating the parent's state, which can make your app's data flow harder to understand. But if the parent does not actually handle state and your child component's data does not relate with each other, mutating the props inside the child component will be fine.

Trying Electron-React Boiler Plate Use #react-pdf/renderer to display PDF Component with PDFViewer Setup

Has anyone set up electron to pass the PDFViewer component that is then displayed to the DOM from React? I am able to display an empty box because the blob file and html aren't passed to the DOM like it does in a simple React app. The blob file is asked to be saved somewhere instead of just being used to the DOM as the simple React app does.
I thinking the PDFViewer information needs to be passed through the package.json/webpack somehow to the electron main.dev.ts file to properly display to the DOM.
I also get a memory leak due to PDFViewer being mounted and unmounted:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in InternalBlobProvider (created by PDFViewer)
in PDFViewer (at tearDownSummery.tsx:9)
in div (at tearDownSummery.tsx:8)
This is what I have to call my pdf component I setup that works up to the point to displaying to the DOM. The download link works and I get the PDF I structured through the .
import React from 'react';
import { PDFViewer, PDFDownloadLink } from '#react-pdf/renderer';
import ReactDOM from 'react-dom';
import TearDownPDF from './tearDowSummeryPDF';
export default function TearDownSummery() {
return (
<div>
<PDFViewer>
<TearDownPDF />
</PDFViewer>
<PDFDownloadLink document={<TearDownPDF />} fileName="IIR.pdf">
{({ blob, url, loading, error }) =>
loading ? <i> Loading document...</i> : <i> Download Pdf </i>}
</PDFDownloadLink>
</div>
);
}
ReactDOM.render(<TearDownSummery />, document.getElementById('root'));
Here is my GitHub project: https://github.com/staniszmatt/iir_Report.git
It is all set up on the pdfSetup branch.
Currently, Electron doesn't have the capability to use #react-pdf based off this post I found.
https://github.com/electron/electron/issues/13038
I'll have to come back to answer again if and when electron adds this capability.

Is it better to send redux state down to children as Props or for the Children to directly read from redux state?

I realize this is a fundamental question that may have been answered before, but I'm looking for a definitive answer, with perhaps some reasoning, as I've not quite found one that convinces me that there is better/best/preferred way to do handle this.
Scenario: A dashboard component receives redux state via connect. Some of the data is shared across the dashboard and its children. Some of the data is specific to the dashboard's children.
Question: Should I always pass the props down to the child components (something) like the below, or should I always connect the child components to redux and read the needed data directly from redux state?
import React, { Component } from "react";
import { connect } from "react-redux";
import ChildOne from ".ChildOne";
import ChildTwo from ".ChildTwo";
class DashboardExample extends Component {
render() {
const { sharedData, childOneData, childTwoData } = this.props
return (
<div>
<h1>{sharedData.selectedDate}</h1>
<ChildOne sharedData={sharedData} childOneData={childOneData} />
<ChildTwo sharedData={sharedData} childTwoData={childTwoData} />
</div>
);
}
}
const mapStateToProps = state => ({
sharedData: state.dashboardData,
childOneData: state.childOneSpecificData,
childTwoData: state.childTwoSpecificData,
});
export default connect(mapStateToProps)(DashboardExample);
As Dan Abramov said, it’s nice to have a division between Presentational Components and Container Components.
Presentational Components
Are concerned with how things look.
May contain both presentational and container components** inside,
and usually have some DOM markup and styles of their own.
Often allow containment via this.props.children.
Have no dependencies on the rest of the app, such as redux actions
or stores.
Don’t specify how the data is loaded or mutated.
Receive data and callbacks exclusively via props.
Rarely have their own state (when they do, it’s UI state rather than
data).
Are written as functional components unless they need state,
lifecycle hooks, or performance optimizations.
Container Components
Are concerned with how things work.
May contain both presentational and container components** inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
Provide the data and behavior to presentational or other container components.
Call redux actions and provide these as callbacks to the presentational components.
Are often stateful, as they tend to serve as data sources.
Are usually generated using higher order components such as connect() from React Redux, createContainer() from Relay, or Container.create() from Flux Utils, rather than written by hand.
source post
————————————
Specific answer to your question:
I find it helpful to try and stick with the principles stated above. It makes your code easy to reason about and it helps to separate concerns (Views / Business logic).
But, if you find yourself writing spaguetti props to stick to it, or if it doesn’t feel natural in a specific piece of code, just connect your Presentational Component.

Angular2 Custom Component with bindable property - how to [(value)] without #Output in custom component?

I have a custom component with an input property as follows:
export class MyComponent{
#Input() value:number;
}
So that I can plop one on a parent component:
<my-component [(value)]="someValueAtParentComponent"></my-component>
Note that I did not provide #Component decorator and the class for the parent component because I don't think those are relevant.
Now, things happen internally in MyComponent that can change the value of value.
From inside MyComponent's template, I display {{value}}, and it displays the correct value throughout its lifetime.
From the parent component's template, I display {{someValueAtParentComponent}}, but it doesn't update with MyComponent's value. I thought [(value)] will automatically do the job, but I guess not.
I don't want to create an #Output event on MyComponent for the parent component to handle the event where it would set someValueAtParentComponent explicitly.
I believe Angular wants to emit an event for a parent component to handle, but that seems very tedious. Is there something we can do in our own components so that we may use the syntactic sugar [(value)] instead of [value]="..." (onValueChanged)="onValueChangedHandler($event)"?

What is the correct way to call a component method in many other components in React?

I am using React with Meteor. I am currently building an app that has grown to have a sizeable number of components (some nesting quite deeply, like 5 or more levels).
I often find myself having to pass props from the parent all the way to the children, just to call a component method for a component that has been rendered in the topmost parent, like this:
Parent File
openDialog() {
this.setState({ open: true });
}
render() {
return (
<div>
<Dialog open={ this.state.open } />
<ChildComponent openDialog={ this.openDialog.bind(this) } />
</div>
);
}
ChildComponent
render() {
return (
<div>
<GrandChildComponent openDialog={ this.props.openDialog } />
</div>
);
}
And so on, just to call the openDialog method defined right at the topmost parent.
This works if you only have one branch going deeper inwards. However if you have say, a login modal dialog which can be triggered from many different parts of a site (header, sidebar, inline links, etc), it is obviously impractical to pass in props this way into every single component which could possibly require the link (or not).
What is the correct (recommended) way to handle this kind of issue?
The common solution is to link your component to an external set of actions and an external State Manager. Flux architecure is used for that. And several frameworks, like Redux, help you integrate it with React.
With flux, you can dispatch an action (openDialog for example) from every component without having to pass it through the whole tree of components.

Resources