In this simple Create-React-App application , I have a simple, static, Header component. For readability the header is held in a separate component. When using : Dveloper Tools - React - and selecting heighlight updates, I'm surprised to see that the Header component renders each time the destination changes. Of course this happens because the state of the parent, the App component, changes.
It was originally build as a functional component; I tried changing it to a React.pureComponent and React.Component with a 'shouldComponentUpdate' function that returns false but it did not help - the component still gets updated/rendered.
I guess this gets to the 'Virtual Dom' and does not render to the actual dom, but in more complicated apps it is still costly. Any suggestions?
Code
Update
I've forked the original repository to demonstrate the issue. In this example the Header component is build with React.Component and shouldComponentUpdate returns false. Yet the header renders each time the destination changes.
Code
When returning false from the ShouldComponentUpdate method React does not run the render method. I confirmed it by adding a console.log command.
However Chrome’s React extension - heighlight updates - still heiglights the Header. The reason for it might be that Header is a sub-component of the App Component, and since the render method of App runs, the Header is heighlighted.
The simplest solution I can think of is to convert your App component to a simple wrapper component around ControlPanel and presentation. Create a new App component which includes the Header and Footer, along with the wrapper component. Please ensure that the App does not have any state of it's own, to avoid re-renders.
My suggestion is to not worry about it, just keep your render functions as cheap as possible and let React do its work.
If you take care to just pass inn the needed props to any component, keep the components as simple as possible and in a sane structure, and make any expensive calculations outside the simple components (to keep them between state changes), that's all the optimizing I would do.
Currently Header is not a component that can implement shouldComponentUpdate.
Implement Header like this:
import React from 'react'
import '../App.css'
import globeLogo from './globe.svg'
export default class Header extends React.Component{
shouldComponentUpdate(nextProps, nextState) {
//compare props and state if need to and decide whether to render or not
//Other wise just return false;
}
render(){
return (
<div className="App-header">
<img src={globeLogo} className="App-logo" alt="logo" />
<h1>Choose My Next Destination</h1>
</div>
)
}
}
Hope that will resolve your query :)
Related
everyone, I am currently working on a React/Electron project and am kind of stumped on how to meet my client's requirements of having less renders when using the useEffect hook. In my current project, I am using a container/component structure so I have my index.js file that contains all the logic for the component and the useEffect in question. The useEffect in the index.js is intended to pre-populate a file input if the file exists, however, this is what is causing the extra render since the component is rendering before the useEffect is finished and then once it is finished the home component then re-renders again with the updated data. So my question is is there a way to have the useEffect finish before home component renders the first time or is this just a part of React that cannot really be changed and my client will have to accept?
useEffect(() => {}, [])
Empty array at the end means this useEffect doesn't have any deps so it will run only once at the beginning.
ref: https://reactjs.org/docs/hooks-reference.html#useeffect (yellow note below)
I am a newbie with React and jsx.
I have a project where I am using React for the first time, but there are still some parts of the page which are not React-based, they use some other framework. Until that older code is refactored to use React or some agnostic way I will need to use both frameworks for now.
This other framework needs to be lazily included on the page, so it might take some time to load. Once available, I can create an object and call .placeAt(id) to tell the object where to render its DOM.
The below code is just a sample of what my current solution looks like.
import React from 'react';
import loadWidget from './loadWidget';
function App() {
return (
<div id="app"></div>
);
}
// loadWidget returns a Promise object which resolves with the Widget class asynchronously
// I need to create a new Widget that will then be placed into the App's <div> using the ID
loadWidget().then(Widget => {
new Widget().placeAt('app'); // Renders into the div with id "app"
});
export default App;
The code above works, but there are some issues with it that make it clear to me that I must not be well adapted to this React programming model yet, where I'm more used to Object oriented programming. In the code above it only works if the index.js calls the App() function exactly once and it must be called prior to the loadWidget() promise having returned. In my case, this is always true since the call to App is synchronous and I know it will only happen once, but I am not satisfied with the solution.
You can simply use other life cycle methods of React.
From what I can understand you're looking for a way to load them on based on
I believe what you're looking for can be adapted to
componenetDidUpdate(props) which will be called every time your props or states will be called.
So what you can do is use a State and then put the updated value in the state for which you need to render the HTML.
So something like this
<div> Render some HTML by ${myStateVariable} </div>
This would help you render your choice of HTML but there're some implications to it, I would recommend you to first read some materials such as
React life cycle components
enter link description here
States and Props
enter link description here
I am working on a project that I inherited from someone else, and I see a lot of <p-xxxx> tags, such as <p-page :has-something="val1" :has-another="val2" />, etc.(e.g. CompName -->
I'm looking around the directories and found a component called Page.vue that has such props in it: has-something and has-another. And structurally speaking, I'm sure the <p-page> corresponds to this component.
So how did this work? I checked the component's name field and it says Page.
EDIT:
I should also note that the component isn't registered at all. It's not imported either. I'm guessing it has something to do with
import '#/globals';
import '#/plugins';
in main.js, because I know we're using our proprietary UI component library. Can anyone point to where I can go read more about how this works? I thought I was pretty good at Vue, but apparently not good enough.
It depends on how the component is registered in the parent component, for instance, if the Page component is registered as:
components: {
PPage: Page
}
Then in the template, you'll refer to this component as <p-page ...
I figured it out.
In our proprietary library we're using, components were being exported out with p- as a prefix, and the library was injected into the whole app via vue.config.js, so there wasn't any importing in individual components.
I had a job interview and the recruiter asked me about "handle the partial updates and manage application size"
For example he explained and displayed a SPA that size was 8MB and he said it's not ideal and perfect !?!?
And he said we should manage the application size with different methods !?
For a test, after the interview session I checked the linkedin website with google chrome DevTools. after any requests I saw response who that was html web page (Html, Css, JS) and apparently linkedin after each requests appends html response to page who it's an idea to control SPA size !
So I have a question, by default in create-react-app package we have webpack to create web modules and that load all components to one bundle.js and this js file will be heavy for 40 or more component. maybe 10MB or more than ...
How can I implement a real and optimized SPA structure with a perfect and accurate partial update method ?
Unfortunately I just know a little of English, please forgive me if I had mistake to write English :-) ;-)
Thank you
I think what you are looking for is Dynamic imports or asynchronously loading components(or more code) whenever needed. There are various ways you can do this like
Load when the user scrolls down towards the components
Only Load the component when a user clicks a button (ex. a Modal)
Load the component after the initial critical data is already rendered(ex. only ldownload the code for the component after its parent component is already loaded and rendered to the dom).
The last example can be done like this :
class Dynamic extends Component {
constructor(props) {
super(props);
this.state = { module: null };
}
componentDidMount() {
const { path } = this.props;
import(`${path}`)
.then(module => this.setState({ module: module.default }))
}
render() {
const { module: Component } = this.state; // Assigning to new variable names #see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
return(
<div>
{Component && <Component />}
</div>
)
}
}
What the above code is doing is loading the Component code after its parent component is already loaded by importing it in component did mount.
This code-splitting method is currently
supported by create-react-app.
read more here
Also check this react-loadable
I suggest you look at lazy loading concepts in ReactJs documentation. It is basically importing only when need arrives and reduces bundle size.
ReactJS Code splitting Documentation
I am currently working on learning React and Redux. Now I am getting a better grasp on what the two do:
React - Render components on the page
Redux - Keep the state of the page
My question though is: what should I actually be rendering with React? Is React suppose to render the entire page, even the header that won't change? For instance, am I suppose to create a new component for the header (logo and tabs, not changing), or just add that to the HTML file I will be rendering to?
I would suggest adding absolutely everything as a React component. Have a single <div> in your html file that you mount your React app to. I found that when I started using React I would try and avoid writing extra code (sure, writing a component for a header rather than the raw HTML is extra lines).
But this introduces complexity, in a way. Different parts of your app are rendered differently. In the long run, in my experience, consistency and readability is more important than fewer lines of code.
BTW if you're using stateless functional components (which your header would be), it's barely any extra code.
import React from 'react';
export default Header = () => <header>My wonderful app</header>;
like most other frameworks, you will have your base 'index.html' file that will include all of your dependencies and then a body which contains a div that you will render your react components into. it will look something like this:
<html>
<head>
<-- script, css, framework files added here -->
</head>
<body>
<div id="reactApp"</div>
</body>
</html>
then your main app file in react will have something along the lines of this at the bottom:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('reactApp')
);
everything else can be rendered within React and passed along to that div view.
It's entirely possible to have a hybrid page. For example: keep the navbar as native HTML where as the content is React.
Remember, React is component oriented so you could think of it as small widgets.
However, you will often have different widgets share the same state. In this case, it's good to make them part of the same tree of components.
Your question doesn't have a definite answer. It depends on what your application state needs are, but use React for the dynamic pieces of your page. Those parts that you're thinking are going to change without a reload will probably keep a state, so that's where React's stage management could come in handy.