In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "analyzing React components, Hooks and performance". The content of the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "analyze React components, Hooks and performance".
As pointed out in the * * section of our React tutorial, it's relatively easy to get started with React. First initialize a new project using Create React App (CRA), and then start development. Unfortunately, over time, the code may become difficult to maintain, especially if you are not familiar with React. Components may get bigger, or you may end up with a bunch of components that are not components, and you may end up writing repetitive code everywhere.
It's time for you to try to start a real React journey-Think in React.
Whenever you develop a new program and you need to make a new design for it that will be converted to React applications in the future, first try to identify the components in the design sketch, how to separate them to make them more manageable, and which elements are repetitive (or their behavior). Try to avoid adding code that may be "useful in the future"-it's tempting, but the future may never come, and you'll leave behind a bunch of extra general features / components with a lot of configurable options.
In addition, if a component is greater than the height of two or three windows, it may be worth separating (if possible)-- it's easier to read later.
Controlled and uncontrolled components in React
In most applications, you need to enter and interact with users in some form, allowing them to enter content, upload files, select fields, and so on. React handles user interactions in two different ways-controlled and uncontrolled components.
As the name implies, the value of the controlled component is controlled by React and can provide values for elements that interact with the user, while uncontrolled elements do not get value attributes. Thanks to this, we can use the React state as a single source of fact, so what we see on the screen is consistent with what we currently have. The developer needs to pass a function that responds to the user's interaction with the form, which changes its state.
Class ControlledInput extends React.Component {state = {value: ""}; onChange = (e) = > this.setState ({value: e.target.value}); render () {return ();}}
In the uncontrolled components of React, we don't care about the change in value. If we want to know the exact value, we just need to access it through ref.
Class UncontrolledInput extends React.Component {input = React.createRef (); getValue = () = > {console.log (this.input.current.value);}; render () {return ();}
So how should I choose? It is possible to use controlled components in large numbers, but there are some exceptions. For example, one case where an uncontrolled component is used is file type input, because its value is read-only and cannot be set in encoding (user interaction is required). In addition, I find controlled components easier to understand and use. Validation of controlled components is based on re-rendering, the state can be changed, and problems in the input can be easily displayed (such as malformed or empty input).
Refs
We mentioned refs earlier, which is a special feature that can be used in class components until hooks appears in 16.8.
Refs can give developers access to React components or DOM elements through references (depending on the type of ref we attach). * use them only in necessary scenarios because they make the code difficult to read and break the data flow from top to bottom. However, they are necessary in some cases, especially on DOM elements (for example, changing focus by coding). When attaching to React component elements, you are free to use the methods in the referenced component. However, this practice should be avoided because there are better ways to deal with it (for example, to promote the state and move the functionality to the parent component).
Refs can also do this:
Use the literal amount of a string (left over from history, should be avoided)
Use the callback function set in the ref property
By creating ref as React.createRef (), binding it to the class property, and accessing it (note that references will be provided during the componentDidMount lifecycle).
One case where a reference is not passed is when a high-level component is used on a component-- understandably, because ref is not a prop (similar to key), so it is not passed down, and it will reference the HOC instead of the component wrapped by it. In this case, we can use React.forwardRef, which takes props and ref as parameters, which can then be assigned to prop and passed to the component we want to access.
Function withNewReference (Component) {class Hoc extends React.Component {render () {const {forwardedRef,... props} = this.props; return;}} return React.forwardRef ((props, ref) = > {return;});}
Error boundary
The more complicated things are, the more likely they are to go wrong. This is why there are wrong boundaries in React. So how do they work?
If there is a problem and there is no error boundary as its parent, it will cause the entire React application to fail. Not displaying information is better than misleading users and displaying error messages, but that doesn't mean you should allow the entire application to crash and display a blank screen. Through the wrong boundary, you can get more flexibility. You can use and display an error message throughout the application, or use it but not display it in some widgets, or display a small amount of information to replace these widgets.
Keep in mind that it only deals with declarative code, not imperative code that you write to handle certain events or calls. For these cases, you should still use the regular try/catch method.
Messages can also be sent to the Error Logger you use at the error boundary (in the componentDidCatch lifecycle method).
Class ErrorBoundary extends React.Component {state = {hasError: false}; static getDerivedStateFromError (error) {return {hasError: true};} componentDidCatch (error, info) {logToErrorLogger (error, info);} render () {if (this.state.hasError) {return Help, something went wrong.;} return this.props.children;}}
High-order component
High-level components (HOC) are often mentioned in React, which is a very popular pattern and you may use it (or already use it). If you are familiar with HOC, you may have seen withNavigation,connect,withRouter in many libraries.
HOC is just a function that takes components as parameters and returns new components with extended functionality compared to components without HOC wrappers. Thanks to this, you can implement some extensible features to enhance your components (for example, access navigation). HOC also has some other forms of invocation, depending on what we currently have, and the only argument must be passed in a component, but it can also accept additional arguments-- some options, or, as in connect, first call a function using configurations, which later returns a component with parameters and HOC.
Here are some things you should do and avoid:
Add the display name to the wrapper HOC function (so you know exactly what it is for, actually by changing the display name of the HOC component).
Don't use HOC in the rendering method-you should use enhancements in it instead of creating a new HOC component there, because it keeps reloading and losing its current state.
Static methods are not automatically copied, so if you want to use some static methods in the newly created HOC, you need to copy them yourself.
The Refs involved will not be passed, so use the previously mentioned React.forwardRef to resolve these issues.
Export function importantHoc () {return (Component) = > class extends React.Component {importantFunction = () = > {console.log ("Very Important Function");}; render () {return ();}};}
Style
Style is not necessarily related to React itself, but it is worth mentioning for a variety of reasons.
First of all, the regular CSS/ inline style works here, you just need to add the class name in the CSS to the className property, and it will work. The inline style is slightly different from the regular HTML style. Style attributes also use hump naming, so border-radius becomes borderRadius.
React seems to promote solutions that are not only common in React, such as the recently integrated CSS module in CRA, where you can simply import name.modules.css and use its properties to adjust the style of the component (some IDE (such as WebStorm) also have autocomplete function, which can tell you the available name.
Another popular solution in React is CSS-in-JS (for example, the emotion library). Furthermore, the CSS module and emotion (or generally speaking, CSS-in-JS) have no restrictions on React.
Hooks in React
Hooks is probably the most eagerly anticipated complement to React since it was rewritten. Can this product live up to expectations? From my point of view, yes, because it's really a great feature. They essentially bring new experiences, such as:
Allows you to delete many class components that we only use rather than own, such as local state or ref, so the component's code looks easier to read.
It allows you to use less code to achieve the same effect.
Make functions easier to understand and test, for example, with react-testing-library.
You can also take parameters, and the result returned by one hook can be easily used by another hook (for example, setState in useEffect is used by useState).
A better way to shrink than a class is often more problematic for minifiers.
It is possible to delete HOC and render props in your application, and although hook is designed to solve other problems, new problems will be introduced.
Can be customized by skilled React developers
The default React hook is rare. Three of the basic hook are useState,useEffect and useContext. There are others, such as useRef and useMemo, but for now let's focus on the basics.
Take a look at useState first, let's use it to create a simple counter. How does it work? Basically, the whole structure is very simple:
Export function Counter () {const [counter, setCounter] = React.useState (0); return ({counter} setCounter (counter + 1)} > +);}
It calls with initialState (value) and returns an array with two elements. Because the array deconstructs the allocation, we can immediately assign variables to these elements. * one is the updated state, and the other is the function we will use to update the value. It looks quite easy, doesn't it?
In addition, because these components were once called stateless functional components, this name is no longer applicable because they can have the state shown above. So it seems that class components and function components are more in line with their actual operation, starting with at least 16.8.0.
The update function (setCounter in our case) can also be used as a function that takes the previous value as an argument in the following format:
SetCounter (prevCounter = > prevCounter + 1)} > + setCounter (prevCounter = > prevCounter-1)} >-
Unlike the this.setState class component that performs a shallow merge, the setting function (setCounter in our example) overrides the entire state.
In addition, initialState can also be a function, not just a normal value. This has its own benefits because the function will only run during the initial rendering of the component and will no longer be called.
Const [counter, setCounter] = useState () = > calculateComplexInitialValue ()
* if we want to use the exact same value of setCounter as at the same time in the current state (counter), then the component will not be re-rendered.
On the other hand, useEffect adds side effects to our functional components, whether it's subscriptions, API calls, timers, or anything we think is useful. Any function we pass to useEffect will run after render and will be executed after each rendering, unless we add a restriction that takes the property that needs to be changed when it should be rerun as the second argument to the function. If we just want to run it on mount and clean it up on unmount, we just need to pass an empty array in it.
Const fetchApi = async () = > {const value = await fetch ("https://jsonplaceholder.typicode.com/todos/1"); console.log (await value.json ());}; export function Counter () {const [counter, setCounter] = useState (0); useEffect () = > {fetchApi ();}, []) Return ({counter} setCounter (prevCounter = > prevCounter + 1)} > + setCounter (prevCounter = > prevCounter-1)} > -;}
Because the empty array is taken as the second parameter, the above code is run only once. In this case it is similar to componentDidMount, but it will be triggered later. If you want to call a similar hook before the browser processes, you can use useLayoutEffect, but these updates will be applied synchronously, unlike useEffect.
UseContext seems to be the easiest to understand because we provide the context we want to access (provided by the object returned by the createContext function), and it provides us with the value of that context.
Const context = useContext (Context)
* to write your own hook, you can write something like this:
Function useWindowWidth () {let [windowWidth, setWindowWidth] = useState (window.innerWidth); function handleResize () {setWindowWidth (window.innerWidth);} useEffect () = > {window.addEventListener ('resize', handleResize); return () = > window.removeEventListener (' resize', handleResize);}, []); return windowWidth;}
Basically, we use regular useState hook, which we specify as the initial value of the window width, and then add a listener to the useEffect that will trigger the handleResize when the window is resized. We will know in time after the component is uninstalled (check the return value in useEffect). Isn't it easy?
Note: use is important in hook. It is used because it allows React to check if you have done something bad, such as calling hook from a regular JS function.
Type check
Before supporting Flow and TypeScript, React had its own property checking mechanism.
PropTypes checks to see if the props received by the React component is consistent with our content. If it is consistent (for example, it should be an object rather than an array), you will receive a warning in the console. It is important to note that PropTypes checks only in development mode because they affect performance and display the above warning in the console.
Since React 15.5, PropTypes has been put into different packages and needs to be installed separately. It declares attributes in a static property called propTypes (surprise), which can be used in conjunction with defaultProps and used if the attributes are not defined (undefined is the only case). DefaultProps has nothing to do with PropTypes, but they can resolve some warnings that may arise because of PropTypes.
The other two options are Flow and TypeScript, which are now more popular (especially TypeScript).
TypeScript is a type superset of JavaScript developed by Microsoft that checks for errors before the program runs and provides excellent autocomplete functionality for development work. It also greatly improves the refactoring process. Supported by Microsoft, it has rich typed language features and is a fairly safe choice.
Unlike TypeScript, Flow is not a language, but a static type checker for JavaScript, so it is more like a tool in JavaScript than a language. The whole idea behind Flow is exactly the same as TypeScript. It allows you to add types to eliminate possible errors before running the code. Just like TypeScript, CRA (creating React App) supports Flow from the start.
I find that TypeScript is faster (almost instant), especially in autocompletion, where Flow seems a little slow. It is worth noting that IDE such as WebStorm, which I use myself, integrates with Flow using CLI. But it seems easier to integrate options in a file, simply adding / / @ flow to the beginning of the file for type checking. In addition, as far as I know, it seems that TypeScript finally won the battle against Flow-it is now more popular, and some libraries are moving from Flow to TypeScript.
More options are mentioned in the official documentation, such as Reason (developed by Facebook and popular in the React community), Kotlin (a language developed by JetBrains), and so on.
Obviously, the easiest way for front-end developers is to use Flow and TypeScript instead of switching to Kotlin or F#. However, this may be easier for back-end developers who are transitioning to the front end.
Production mode and React performance
For production mode, the most basic and obvious change you need to make is to switch DefinePlugin to "production" and add UglifyJsPlugin in the case of Webpack. In the case of CRA, it is as simple as using npm run build (which will run react-scripts build). Note that Webpack and CRA are not the only options, because you can use other build tools, such as Brunch. This is usually included in official documentation, whether it's official React documentation or tool-specific documentation. To make sure the pattern is set correctly, you can use React Developer Tools, which will tell you how to configure the build (production and development) mode you are using. The above steps will allow your application to run without checks and warnings from React, and the bundle itself will be minimized.
You can do a lot more for the React app. What do you do with the built JS file? If the size is relatively small, you can start with "bundle.js" or do something like "vendor + bundle" or "vendor + minimize required parts + import things when needed". When you are dealing with a very large application, you don't need to import everything in the first place. Note that bundling some unused JavaScript code in the main bundle will only increase the size of the bundle package and slow down the load of the application at startup.
Vendor bundles may be useful if you plan to freeze versions of libraries and think they may not be changed for a long time. In addition, larger files are more suitable for gzipping, so the benefits from splitting may sometimes not be worth it. It depends on the size of the file, and sometimes you need to try it yourself.
Code split
There are a lot more ways to split the code than the advice given here, but let's focus on what is available to CRA and React itself. Basically, in order to divide the code into different blocks, you can use import (), which can be supported by Webpack (import itself is a phase 3 proposal, so it is not yet part of the language standard). Every time Webpack sees import, it knows that it needs to start splitting the code at this stage and cannot include it in the main package (its code in import).
Now we can connect it to React.lazy (), which requires a file path of import () that contains the components that need to be rendered in that place. Next, we can use React.suspense (), which displays different components in that location until all the imported components are loaded. One might wonder, if I were to import a single component, would I not need it?
In fact, this is not the case, because React.lazy () will show the components of our import (), but import () may get larger blocks than individual components. For example, this component may contain other libraries, or more code, so you don't just need a file-- it may be multiple files tied together. * We can wrap all of this in ErrorBoundary (you can find the code in the section on error boundaries in this article) if something fails because of the component we want to import (for example, a network error), this will be used as an alternative.
Import ErrorBoundary from'. / ErrorBoundary'; const ComponentOne = React.lazy (() = > import ('. / ComponentOne')); function MyComponent () {return ();}
This is a simple example, but obviously you can do more. You can use import and React.lazy for dynamic routing partitioning (for example, administrators and regular users). Note that React.lazy only supports default exports and does not support server-side rendering.
React code performance
With regard to performance, if your React application is slow, there are two tools that can help you find the problem.
* is Chrome Performance Tab, which tells you what happens to each component (for example, mount,update). With it you should be able to determine which components may have performance problems and then optimize them.
Another option is DevTools Profiler, which is available in React 16.5 + and in conjunction with shouldComponentUpdate (or PureComponent, explained in the * * section of this tutorial), we can improve the performance of some key components.
Obviously, basic optimization of the network is *, such as de-dithering for some events (for example, scrolling), being cautious about animation (using transformations rather than changing height and animating), and so on. These issues are easy to ignore, especially if you have just mastered React.
The status quo of React in 2019 and beyond
If I want to discuss the future of React, I personally don't care too much. From my point of view, React's position in 2019 and beyond is hard to shake.
React has such a strong position that it is difficult to abandon it with the support of a large community. The React community is great, it always generates new ideas, and the core team is constantly working to improve React, add new features and fix old problems. React is also supported by a big company, but the license is no longer a problem-it now uses MIT license.
Yes, there are things that are expected to change or improve; for example, to make React slightly smaller (one of the measures mentioned is to delete composite events) or to rename className to class. Of course, even these seemingly small changes can lead to problems such as affecting browser compatibility. Personally, I also want to know what happens when WebComponent gains more popularity, because it may add some of the things that React often uses. I don't believe they will be a complete replacement, but I believe they can complement each other very well.
As for the short term, hook has just been added to React. These may be changes that have taken place since React rewriting, as they will bring more possibilities and enhance more functional components (now they are really much hyped).
*, as I said recently, there is React Native. For me, this is a great technology that has changed a lot in the past few years. React Native is rewriting its core, which should be done in a similar manner to React rewriting (it's all internal, and almost nothing should be changed for developers). Asynchronous rendering becomes a faster and lighter bridge between native and JavaScript. Of course there are more changes.
There's a lot to look forward to in the React ecosystem, but the update to hook (and React Native, if anyone likes mobile apps) will probably be the most important change we'll see in 2019.
Thank you for reading, the above is the content of "analyzing React components, Hooks and performance". After the study of this article, I believe you have a deeper understanding of the analysis of React components, Hooks and performance, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.