Summary of react interview questions 1

React event binding principle

The principle of React event binding is based on the synthetic event (SyntheticEvent) system. In React, event binding is achieved by passing event handler functions as attributes to specific component elements. When an event is fired on an element, React creates a synthetic event object and passes it to the event handler.

React's event system uses the concept of event delegation to delegate event processing logic to the top-level container element, and then use event bubbling to handle these events. This approach brings performance advantages because a small number of event handler functions are attached to the top of the entire component tree rather than to each individual element.

In addition, React also provides cross-browser consistency and performance optimization by encapsulating and optimizing synthetic events, allowing developers to process events in a more unified and reliable way.

What are the disadvantages of setState in React?

setStateIn React, it is a method used to update component state. Although it is a very convenient and powerful tool, it also has some shortcomings that need to be noted:

  1. Asynchronous update: setState is asynchronous, so you cannot rely on getting the update immediately after setState status. React may batch or delay updates to setState , which may cause some unexpected behavior, especially when making multiple consecutive updates to state.
  2. Performance impact: When setState is called, React will trigger a re-rendering of the component. Frequent use of setState may cause performance issues, especially if the component hierarchy is deep or the state data is large.
  3. May cause unnecessary re-rendering: setState will trigger a re-rendering of the component even if the state has not actually changed. This may result in unnecessary performance consumption.
  4. Not suitable for handling synchronous updates: Using setState may cause problems if the update relies on a previous state. Because setState is asynchronous, there is no guarantee that the latest status value will be obtained.

In order to solve these problems, you can use the function form of setState. This function will receive the previous state as a parameter, thus avoiding the problem of relying on the previous state. Additionally, for updates that depend on previous state, you can use a callback function of setState to ensure execution after the state update is complete. In addition, if you need synchronous status updates, you can use this.state to perform the operation directly, but make sure there are no unexpected side effects.

How to implement React component communication

Communication between React components can be achieved in the following ways:

  1. Props: The most common way is to communicate between parent and child components through props. Parent components can pass data to child components as props, and child components can receive and use these data through props.
  2. Callback function: The parent component can pass the function to the child component as props, and the child component can call this function to notify the parent component that certain events have occurred or certain states have changed. .
  3. Context: React provides a context API that allows passing data in the component tree without having to pass props layer by layer. This approach is suitable for sharing data throughout the application, but it needs to be used with caution to avoid overuse of contexts that lead to tight coupling between components.
  4. Global state manager (such as Redux, MobX): Use the state management library to abstract the state into the global world, and multiple components can access and modify these states. This approach is suitable for state sharing and management in large applications, but introduces additional concepts and complexity.
  5. Event Bus: You can use the event bus mode to create an event center, allowing each component to subscribe to or publish events to achieve communication between components. But event names and subscriptions need to be managed carefully to avoid event naming conflicts and hard-to-track problems.
  6. Ref: Ref can be used to directly access the instance or DOM element of the subcomponent. However, it is recommended to use Ref with caution because it destroys the encapsulation of React components and makes the dependencies between components unclear.

Depending on specific scenarios and needs, choosing the appropriate communication method can better organize and manage the status and data flow of React applications.

The difference between class components and function components

Class components and function components are two different types of components in React, and they have some differences:

  1. Language:
    • Class component: Use the ES6 class keyword to define components, inherited from React.Component, which includes life cycle methods and state.
    • Function component: Define the component in the form of a function, and use the function body to describe the UI of the component. Previously, function components had no state or life cycle methods, but with the introduction of React Hooks, function components can use Hooks such as useState to manage state, and useEffect to handle side effects and life cycle related logic.
  2. State:
    • Class component: Owns component state (state) and manages state data through this.state and this.setState().
    • Function component: Previously, function components had no state, but after using Hooks, you can use useState to define and manage state in function components.
  3. Life cycle:
    • Class component: It has complete life cycle methods, such as componentDidMount, componentDidUpdate, componentWillUnmount, etc., which are used to handle the mounting, updating and unmounting process of components.
    • Function component: Before the emergence of Hooks, function components had no life cycle methods, but now you can use useEffect to simulate life cycle behavior and handle side effect logic.
  4. Performance:
    • Class component: Since class components may have additional performance overhead in some cases (such as binding this, more life cycle methods, etc.), they may be better than function components. Slightly slower.
    • Function Component: With the emergence and optimization of React Hooks, the performance of function components has approached or even exceeded class components, especially for simple UI rendering.
  5. Readability and simplicity of writing:
    • Class components: For larger components, class components may appear more complex because they contain more code, such as lifecycle methods, states, etc.
    • Functional Components: Generally more concise, Hooks can make functional components easier to understand and write, especially for simple components that only need to render the UI.

Overall, in React, with the introduction of Hooks, functional components have become more powerful and flexible, can meet most component needs, and are generally easier to understand and maintain. But for some specific scenarios, such as when life cycle methods need to be used or component state management is more complex, class components may still have their place.

Could you please tell me what React’s routing is?

React Router is a library for managing navigation between different pages (or views) in your application. It allows you to implement client-side routing in a React Single Page Application (SPA) without refreshing the entire page.

React Router provides a set of components for defining the routing structure of the application, including Router, Route, Link, etc. Here are some key concepts of React Router:

  1. BrowserRouter sum HashRouter:
    • BrowserRouter: Use HTML5’s history API to handle routing without #.
    • HashRouter: Use the hash part (#) of the URL to process routing, suitable for environments that do not support the history API.
  2. Route combination
    • RouteComponents are the core of React Router and are used to define components that should be rendered under a specific path.
    • Specify the path through the path attribute, and specify the component to be rendered through the component or render attribute.
  3. Link combination:
    • LinkThe component is used to create navigation links in your application, replacing the traditional <a> tag.
    • Specify the target path of the link through the to attribute. When the link is clicked, React Router will prevent the browser's default behavior and avoid refreshing the entire page, but change the URL through JavaScript.
  4. Switch assembly:
    • SwitchThe component is used to wrap multiple Route components, and only the first matching route is rendered.
    • Prevent multiple routes from matching at the same time, resulting in the rendering of multiple components.
  5. Route number:
    • can define parameters by using in path and obtain routing parameters through . :parameterprops.match.params
  6. Installation route:
    • React Router supports nested routing, that is, using Route in a component to define sub-routes to form a nested routing structure.

Using React Router, you can implement dynamic navigation in your application, load different components according to changes in the URL, and maintain partial refresh of the page to improve user experience. This makes navigation in building single-page applications more flexible and user-friendly.

What performance optimization methods does React have?

React has many performance optimization methods. Here are some common methods:

  1. Virtual DOM:
    • React uses a virtual DOM instead of manipulating the actual DOM directly. It maps component state changes to the virtual DOM and then updates them to the actual DOM in batches, reducing the performance overhead caused by directly operating the DOM.
  2. Diff algorithm:
    • React uses the Diff algorithm to compare the before and after state changes of the virtual DOM and only updates the necessary changes, avoiding unnecessary DOM operations and improving performance.
  3. 组件的 shouldComponentUpdate / React.memo
    • shouldComponentUpdate is a life cycle method in a class component, while React.memo is a higher-order component of a function component. They can be used to control whether the component is re-rendered. By comparing the old and new props or state, decide whether to update the component to avoid unnecessary re-rendering.
  4. The unique identifier (Keys) of the list item:
    • When rendering the list, set a unique key for each subcomponent to help React identify changes in the list items more efficiently and reduce the cost of re-rendering.
  5. Avoid unnecessary rendering:
    • When using shouldComponentUpdate or React.memo in a component, avoid creating new objects or functions in the render method. to maintain reference stability.
  6. Lazy loading and code splitting:
    • UseReact.lazy and Suspense to implement lazy loading of components, and use dynamicimport() to implement code division and reduce initial Loading time, improve page loading performance.
  7. Use PureComponents or useMemo/useCallback:
    • PureComponent is a class component in React. It will shallowly compare props and state in shouldComponentUpdate to avoid unnecessary re-rendering. And useMemo and useCallback are React Hooks, which can cache calculation results or callback functions to improve performance.
  8. Event processing optimization:
    • Avoid creating new event handlers during the rendering process and try to reuse existing handlers.
  9. Use the production version:
    • Use a minified and optimized version of React in production to reduce file size and load faster.

These are some common React performance optimization methods, but the specific optimization strategies will vary according to the characteristics and needs of the application. During the development process, monitoring and analyzing application performance and targeted optimization of key parts can more effectively improve application performance.

Have you ever used React hooks and why?

Yes, React Hooks are a new feature introduced in React 16.8. They allow function components to have state management and life cycle processing capabilities similar to class components. I love using them for a few important reasons:

  1. Cleaner code: Using Hooks can make the logic of function components clearer and more concise. Compared with class components, function components use Hooks to more easily manage state, side effects, and logic reuse, reducing boilerplate code.
  2. Better reuse logic: Hooks make logic reuse easier. By customizing Hooks, component logic can be extracted to form reusable functions, allowing logic to be shared between different components.
  3. Easy to test: Functional components are inherently easier to test, and using Hooks makes it easier to write unit tests. Customized Hooks or the logic processed by each Hook can be tested in a targeted manner.
  4. No need to change the component structure: Using Hooks does not require converting function components into class components. It can be used directly in existing function components without changing the structure and syntax of the component.
  5. Improve performance: Reasonable use of Hooks can avoid some performance problems in class components, such as avoiding excessive nesting and reducing unnecessary rendering.

The introduction of React Hooks allows function components to possess most of the capabilities of class components, making React development more flexible and easier. They bring more functionality to functional components, allowing developers to write and organize component logic more naturally and efficiently.

What are the pros and cons of virtual DOM? Implementation principle?

Virtual DOM (Virtual DOM) is an important concept used to improve performance in React. Its advantages, disadvantages and implementation principles are as follows:

Advantage:

  1. Performance improvement: As a lightweight copy in memory, virtual DOM can reduce the performance overhead caused by directly operating the actual DOM. React improves performance by minimizing DOM operations by comparing the before and after state of the virtual DOM and then updating the actual DOM in batches.
  2. Cross-platform compatibility: The concept of virtual DOM does not depend on the actual platform or browser API, so it can be used in different environments, keeping React consistent on various platforms sex.
  3. Simplify complexity: Through the virtual DOM comparison algorithm, React can intelligently select the smallest DOM changes between multiple updates. Developers do not have to manually manipulate the DOM and only need to pay attention to data changes and the status of components, making the code easier to maintain and understand.

shortcoming:

  1. Memory consumption: Virtual DOM needs to maintain a data structure in memory similar to the actual DOM structure, which may occupy some additional memory space.
  2. Increased complexity: For simple applications, introducing virtual DOM may increase the complexity of the code, which may sometimes lead to over-optimization.

Implementation principle:

  1. Create virtual DOM: When the component state changes, React will not directly operate the actual DOM, but creates a virtual DOM tree, that is, a JavaScript object tree to describe the current UI structure.
  2. Compare changes: React uses the Diff algorithm to compare the differences between the old and new virtual DOM trees and find out the parts that require actual DOM updates. The Diff algorithm reduces the number of operations on the actual DOM as much as possible.
  3. Update the actual DOM in batches: React updates the actual DOM in batches based on the results of the Diff algorithm, updating only the necessary changes, thereby reducing performance overhead.

The core idea of ​​virtual DOM is to convert actual DOM operations into in-memory operations, and by comparing the differences between before and after states, the number of updates to the actual DOM is minimized, thereby improving performance and response speed.

The diff time complexity of React and Vue has been optimized from O(n^3) to O(n). So how are O(n^3) and O(n) calculated?

The time complexity referred to here refers to the algorithm complexity of virtual DOM comparison, mainly referring to the Diff algorithm used in React and Vue.

O(n^3) Diff algorithm:

The complexity of the Diff algorithm in earlier versions of React was O(n^3). This complexity is due to the fact that React uses a three-level nested loop to perform virtual DOM comparison, which includes two traversals of the virtual DOM tree and one traversal of the subtree. Such an algorithm may cause performance problems under complex component structures, because when the number of components increases, the comparison time will increase cubically.

O(n) Diff algorithm:

Subsequent versions of React and Vue have optimized the Diff algorithm, reducing the time complexity to the O(n) level. This is mainly due to an algorithm optimization called "double-end comparison". Its core idea is to compare the subtrees of two virtual DOM trees by simultaneously traversing from both ends (head and tail) to the middle, thereby reducing the number of comparisons.

Specifically, the new Diff algorithm will use some strategies to exit unnecessary comparisons as early as possible during the comparison process. For example, when encountering different types of nodes, nodes with different keys, etc., it can be directly determined as nodes that need to be updated to avoid unnecessary comparisons. Necessary recursive comparison.

This double-ended comparison method significantly reduces the complexity of comparison operations, significantly improving the performance of virtual DOM comparison under large component trees.

Let’s talk about the design ideas of Redux and Vuex

Redux and Vuex are libraries for state management, designed to manage and share state in complex applications. They share some common design ideas:

Single Source of Truth:

  • Redux: Redux has a single state tree, also called a "store", and the state of the entire application is stored in this single object.
  • Vuex: Vuex also has a single state tree, called "store", and the state of all components is centrally stored in this state tree.

State immutability (State is Read-Only):

  • Redux: The state of Redux is read-only. The only way to change the state is to trigger an action and update the state through reducers.
  • Vuex: Vuex also follows the principle of immutability of state, and the state can only be modified by submitting mutations.

Actions trigger state changes:

  • Redux: Use dispatch action to describe the event that occurred. Action is an ordinary object containing the type attribute, which is used to describe the event that occurred.
  • Vuex: Trigger state changes through commit mutations. Mutations are a synchronization function used to modify the state.

Use pure functions to handle state changes:

  • Redux: Redux uses reducers to process actions. Reducers are pure functions that receive the previous state and action and return the new state.
  • Vuex: Vuex uses mutations to process actions. Mutations are also pure functions. They receive the previous state and the submitted mutation and return the new state.

Centralized management status:

  • Redux: The Redux store is a centralized data warehouse, and all components share the same state.
  • Vuex: Vuex’s store is also a centralized data warehouse, and components in the entire application can share state.

These design ideas are designed to help developers better organize and manage the status of applications and improve the maintainability and testability of code. Although Redux and Vuex target different frameworks (Redux for React and Vuex for Vue.js), their design philosophies have many similarities, emphasizing state consistency, predictability, and unidirectional data flow.

How to interact with data between different components in React?

In React, data interaction between different components can be carried out in the following ways:

  1. Props:
    • Parent components can pass data to child components through props. This is the most common and recommended way of passing data in React. Parent components can pass data to child components as props, and the child components can receive and use this data through props.
  2. Number of iterations:
    • Parent components can pass functions as props to child components, and child components can call these functions to notify the parent component of the occurrence of certain events or to pass data.
  3. Context:
    • React provides a context API that allows data to be shared across the component tree without having to pass props layer by layer. This method is suitable for sharing data throughout the application and can be accessed by multiple components.
  4. Global state manager (such as Redux, MobX):
    • Use a global state manager to abstract state into the global world, where multiple components can access and modify this state. This approach is suitable for state sharing and management in large applications.
  5. Event Bus:
    • You can create an event center to allow each component to subscribe to or publish events to achieve communication between components. But event names and subscriptions need to be managed carefully to avoid event naming conflicts and hard-to-track problems.
  6. Ref (quotation):
    • Ref can be used to directly access the instance of a child component or DOM element. However, it is recommended to use Ref with caution because it destroys the encapsulation of React components and makes the dependencies between components unclear.

Choosing the right approach depends on your application architecture, data complexity, and the relationships between components. Generally, it is recommended to use props to pass data and callback functions to implement communication between components. For large applications or global state management, you can consider using a state manager or context for data sharing.

What is the role of refs in React?

In React, refs is a special property used to get a reference to a specific DOM element or class component instance. Its function has several aspects:

  1. Access DOM elements: Through refs, you can obtain the corresponding real DOM elements after the component is rendered. This is useful for situations where you need to directly manipulate the DOM, such as getting the value of an input box, setting focus, performing native DOM operations, etc.

    class MyComponent extends React.Component {
          
          
      constructor(props) {
          
          
        super(props);
        this.myRef = React.createRef();
      }
    
      componentDidMount() {
          
          
        this.myRef.current.focus(); // 设置焦点到该元素
      }
    
      render() {
          
          
        return <input ref={
          
          this.myRef} />;
      }
    }
    
  2. Access class component instances: In addition to DOM elements, refs can also reference class component instances. This allows you to call child component methods or access child component properties in the parent component.

    class ChildComponent extends React.Component {
          
          
      doSomething() {
          
          
        // do something
      }
    
      render() {
          
          
        return <div>Hello, I am a child component.</div>;
      }
    }
    
    class ParentComponent extends React.Component {
          
          
      constructor(props) {
          
          
        super(props);
        this.childRef = React.createRef();
      }
    
      componentDidMount() {
          
          
        this.childRef.current.doSomething(); // 调用子组件的方法
      }
    
      render() {
          
          
        return <ChildComponent ref={
          
          this.childRef} />;
      }
    }
    

It should be noted that excessive use of refs should be avoided because it will destroy the encapsulation of components and make the dependencies between components unclear. In most cases, communication between components can be achieved using props and state management. Refs should be used as a means for special cases, such as direct manipulation of the DOM or when you need to access an instance of a specific component.

Please list the react life cycle functions.

In React class components, commonly used life cycle functions include:

  1. Mounting
    • constructor(): The component's constructor, called when the component is created, is used to initialize state and binding methods.
    • static getDerivedStateFromProps(): Triggered when the component is created and updated, used to update state based on props.
    • render(): Rendering function, responsible for rendering the UI of the component.
    • componentDidMount(): Called after the component is mounted to the DOM, usually used to make network requests or subscribe to events.
  2. Updating phase (Updating):
    • static getDerivedStateFromProps(): Will also be called during the update phase to update state based on props.
    • shouldComponentUpdate(): Determines whether the component needs to be re-rendered, returning true by default. Performance optimization can be performed based on old and new props or state.
    • render(): Re-render the component's UI.
    • getSnapshotBeforeUpdate(): Called before updating the DOM, you can obtain the DOM information before the update.
    • componentDidUpdate(): Called after a component update is completed, usually used to handle post-update operations, such as operations after updating the DOM or network requests.
  3. Unmounting:
    • componentWillUnmount(): Called before the component is uninstalled and destroyed, used for cleanup work, such as unsubscribing or clearing timers, etc.
  4. Error Handling:
    • static getDerivedStateFromError(): Used to capture errors thrown by child components and return an alternative UI to display error information.
    • componentDidCatch(): Called after an error occurs in the component and can be used to record error information or send error reports.

It should be noted that after React 17, some lifecycle functions are marked as unsafe and may be deprecated in future versions. React recommends using new lifecycle APIs, such as getDerivedStateFromProps and componentDidCatch to replace the deprecated lifecycle functions.

Which event is executed first, component binding or js native binding event?

In React, the order in which component-bound events and JavaScript natively bound events are fired depends on the specific event type and the browser's event bubbling mechanism.

Event binding in React is usually done through event attributes in JSX, such as onClick, onChange, etc. These event bindings are managed through the event system provided by React, and they are usually executed after native browser events.

When you use events such asonClick in React, you are actually delegating the event to React's synthetic event system, which will respond according to different environments (such as different browsers) Generate corresponding events. These React synthetic events are bound to the document, and then the event bubbling mechanism is used to simulate the capturing and bubbling stages of the event.

When there are both React event bindings and JavaScript native event bindings in a component, if both are bound to the same DOM element and listen to the same type of events, the React synthetic events will be processed after the browser native events. Triggered because React's event system is built on the browser's event system.

It should be noted that React synthetic events will be managed uniformly, and some encapsulation and optimization of events will be done to make React applications more efficient, but it may also cause the order of event triggering to be slightly different from native JavaScript events. Normally this won't be a problem, but if you have special needs, you can use native JavaScript event bindings to bypass React's synthetic event system.

Delayed operation of fetch

When using fetch to make network requests, you can use the setTimeout function to add a delay operation. setTimeout is a function provided by JavaScript, which is used to set the delayed execution of a certain function or code block.

Here is an example of using fetch in conjunction with setTimeout for a delayed operation:

// 定义一个延时函数,返回一个 Promise,在指定的时间后 resolve
function delay(ms) {
    
    
  return new Promise(resolve => setTimeout(resolve, ms));
}

// 使用 fetch 进行网络请求,并添加延时操作
function fetchDataWithDelay() {
    
    
  fetch('https://api.example.com/data')
    .then(response => {
    
    
      // 处理返回的数据
      return response.json();
    })
    .then(data => {
    
    
      // 在请求完成后延时 2000 毫秒
      console.log('Data fetched:', data);
    })
    .catch(error => {
    
    
      // 处理错误
      console.error('Error fetching data:', error);
    });

  // 在请求后延时 2000 毫秒
  delay(2000).then(() => {
    
    
    // 在延时结束后执行的操作
    console.log('Delay finished');
  });
}

In this example, fetch immediately executes a delay functiondelay(2000) after the request is sent, and after the delay ends, "Delay finished" is output. ". This delay operation will not affect the fetch request itself, but will be delayed after the request is sent. It should be noted that this method does not change the timeout of the fetch request, it just performs another delay operation after the request.

A component nests B component, life cycle execution order

When component A nests component B, the execution sequence of the component life cycle is as follows:

  1. Mounting Phase:
    • A set:
      • constructor():A component's constructor is called first.
      • render(): Render the UI of component A.
      • componentDidMount(): Called after component A is mounted to the DOM, component B has not yet been mounted.
    • B combination
      • constructor():The B component's constructor is called.
      • render(): Render the UI of component B.
      • componentDidMount(): Called after component B is mounted into the DOM structure of component A.
  2. Updating Phase:
    If the state of component A changes and causes re-rendering, the update of component A and component B will be triggered. Stage life cycle function:
    • A set:
      • shouldComponentUpdate(): Determine whether component A needs to be re-rendered.
      • render(): Re-render the UI of component A.
      • getSnapshotBeforeUpdate(): Get DOM information before update (optional).
      • componentDidUpdate(): Called after component A is updated.
    • B combination
      • shouldComponentUpdate(): Determine whether component B needs to be re-rendered.
      • render(): Re-render the UI of component B.
      • getSnapshotBeforeUpdate(): Get DOM information before update (optional).
      • componentDidUpdate(): Called after component B is updated.

This means that when parent component A is mounted or updated, child component B will be mounted or updated accordingly. The life cycle function of the child component is called in the corresponding life cycle function of the parent component.

The connection between diff and Key

In React, the diff algorithm is a strategy used for virtual DOM comparison, and using keys is one of the important means to optimize the diff algorithm.

Diff algorithm:

The Diff algorithm is an algorithm used by React to compare the difference between two virtual DOM trees before and after. It compares the nodes of two trees layer by layer to find out the parts that need to be updated, minimizing operations on the actual DOM and improving rendering performance.

Key:

Key is a unique identifier used to help React identify each element in the list. When rendering lists, React uses keys to identify list items, allowing for more accurate DOM reuse, insertion, and deletion operations. Each key should be unique and stable regardless of the order or number of list items.

connect:

Using key can help React identify each element in the list more accurately and assist the diff algorithm in updating and reusing the DOM. When the elements in the list do not have keys, React can only use the default comparison strategy, which may lead to unnecessary DOM operations, such as re-rendering the entire list instead of only partially updating the list items.

Correct use of key can effectively optimize the performance of the diff algorithm, avoid unnecessary DOM operations, and improve the efficiency of list rendering. At the same time, reasonable use of keys can also avoid some potential bugs, such as misalignment or reordering of list items. Therefore, key is an important optimization method in React, which can help React manage and update components more efficiently.

Virtual dom and native dom

Virtual DOM and native DOM are both concepts used in web development to describe and manipulate page structure, but there are some key differences between them:

Primitive DOM (Document Object Model):

  1. Real DOM structure: The native DOM is an abstract representation of the actual page structure in the browser. It consists of a node tree, and each HTML element is a node. These nodes can be directly manipulated and modified through JavaScript, such as changing styles, adding content, etc.
  2. Direct operation: The content and structure of the page can be directly added, deleted, modified, and checked through native DOM operations. However, frequent DOM operations may affect performance, especially for large pages and In case of frequent updates.

Virtual DOM:

  1. In-memory mapping: Virtual DOM is a concept in React or other similar frameworks. It is an abstraction of the real DOM structure and builds a lightweight structure in memory. A tree structure based on JavaScript objects.
  2. Optimize update: When updating data, React uses the virtual DOM to compare, find out the parts that need to be updated, and then update the actual DOM in batches. The virtual DOM uses the Diff algorithm to compare the difference between the before and after states, minimizing the operation of the actual DOM and improving performance.
  3. Batch update: Virtual DOM allows React to perform a large number of comparisons and calculations in memory, and finally updates the actual DOM at once, avoiding the performance overhead caused by direct and frequent operations on the actual DOM. .

Summary of differences:

  • The native DOM is the actual page structure in the browser and can be directly manipulated, but frequent operations may affect performance.
  • Virtual DOM is an in-memory abstraction of the real DOM, used to optimize DOM updates and minimize operations on the actual DOM by comparing differences.

The introduction of virtual DOM allows React to manage and update pages more efficiently, while reducing the performance overhead caused by directly operating the actual DOM, improving the performance and user experience of web applications.

Two new hook functions? What is the difference between it and the canceled will series?

As of the knowledge I have (early 2022), the new hook functions in React include useEffect and useLayoutEffect. These two functions are part of React Hooks and are used to perform side-effect operations in functional components.

useEffect

  • Purpose: Used to handle side-effect operations, such as subscribing to events, asynchronous data acquisition, DOM operations, etc. Similar to the combination of componentDidMount, componentDidUpdate and componentWillUnmount in class components.
  • Execution timing: Executed after each rendering is completed, you can control whether to perform side effects and when to clear them.
  • Features: It is executed asynchronously by default and does not block browser rendering. Can return a cleanup function that cleans up side effects before the component is unloaded.

useLayoutEffect

  • Usage: Also used to handle side-effect operations, but it will be executed synchronously after the DOM is updated and before the browser draws. Typically used when the DOM needs to be updated immediately.
  • Execution timing: Executed synchronously before the browser draws, similar to componentDidMount and componentDidUpdate in class components .
  • Features: It will block the rendering of the browser, so it needs to be used with caution to avoid affecting page performance.

Different will Series:

React version 16.3 introduced useEffect and other Hooks, and marked some will series life cycle functions as unsafe. The main differences are:

  • Execution timing:will The series of life cycle functions will be executed before and after rendering, while Hooks are executed after rendering.
  • Usage:will The life cycle functions of the series belong to class components and need to be used in class components. Hooks are used in functional components.
  • Side Effect Management: Hooks manage side effects through functions such as useEffect, which can manage status and side effect operations within the component, making it more flexible.

Althoughwill the series of lifecycle functions are still valid, the React community recommends using Hooks because they provide a more flexible and reusable way to handle side-effect operations in components. At the same time, it makes the component logic easier to understand and maintain.

How to package and upload image files in react

Uploading image files in React typically requires the following steps:

1. Create a form for uploading files:

import React, {
    
     useState } from 'react';

function ImageUpload() {
    
    
  const [file, setFile] = useState(null);

  const handleFileChange = (e) => {
    
    
    const selectedFile = e.target.files[0];
    setFile(selectedFile);
  };

  const handleSubmit = (e) => {
    
    
    e.preventDefault();
    // 发送文件至服务器或执行其他操作
    if (file) {
    
    
      const formData = new FormData();
      formData.append('file', file);
      // 发送 formData 到服务器
      // 使用 fetch 或其他网络请求库发送 formData
    }
  };

  return (
    <form onSubmit={
    
    handleSubmit}>
      <input type="file" onChange={
    
    handleFileChange} />
      <button type="submit">Upload</button>
    </form>
  );
}

export default ImageUpload;

2. Use FormData to build file data:

In the handleFileChange function, use the FormData object to build the file data. When the user selects a file, selectedFile will be stored in the component's state. You can use FormData to send file data to the server along with other form data when the form is submitted.

3. Send the file to the server:

Send the object to the server using the appropriate network request library (such as fetch, axios, etc.). FormData

const formData = new FormData();
formData.append('file', file);

fetch('/upload', {
    
    
  method: 'POST',
  body: formData,
})
  .then(response => response.json())
  .then(data => {
    
    
    // 处理上传后的返回结果
  })
  .catch(error => {
    
    
    // 处理上传失败情况
  });

This example shows a simple process for uploading images. Depending on your specific needs and server-side requirements, you may need to add more logic to handle file uploads.

Understanding of one-way data flow and two-way data binding, benefits?

One-way data flow and two-way data binding are two different data flow modes that are commonly seen in front-end frameworks.

One-Way Data Flow:

In one-way data flow, the flow of data is one-way, from parent component to child component. When the data changes, new data is passed to the subcomponent through props, and the subcomponent re-renders based on the new data.

benefit:
  1. Traceable data flow: It is easy to track the source and changes of data, and facilitate debugging and maintenance.
  2. Data is more controllable: Data can only flow in one direction, reducing unpredictability and improving code maintainability.
  3. Performance Optimization: Due to the characteristics of one-way data flow, the framework can more easily perform performance optimization, such as selective updates when data changes.

Two-Way Data Binding:

Two-way data binding allows data changes between the view layer and the data layer to affect each other. When the input box in the view changes, the data in the data layer also changes, and vice versa. In frameworks, for example, AngularJS (version 1.x) adopts two-way data binding.

benefit:
  1. Simplify view updates: Data changes will be directly reflected in the view, reducing the code for manually updating the view.
  2. Convenient two-way synchronization: Synchronization of views and data is simpler, and developers do not need to manually update and monitor data.

Selection and applicable scenarios:

  • One-way data flowIt is easier to track data flow, suitable for large applications or complex component structures, and provides more controllable data management.
  • Two-way data binding provides a simpler way to handle synchronization between views and data, suitable for simple pages or rapid prototype development.

Modern front-end frameworks such as React, Vue.js, etc. tend to use one-way data flow, but also provide some mechanisms to achieve some two-way binding effects (such as in Vue.js v-model). Choosing the appropriate data flow pattern depends on project needs, complexity, and developer preferences.

What is the difference between props and state in React components?

In React components, props and state are two core concepts used to manage the data and state of the component. There are several differences between them Key differences:

Props:

  1. Read-only:props is the data passed from the parent component to the child component and is immutable.
  2. External incoming:props are passed from parent components to child components, and child components cannot directly modify their values.
  3. Purpose: Used to pass data between components, similar to function parameters.
  4. Source: It comes from outside the component and is the configuration of the component by the external environment.

State:

  1. Variability:state is the data managed by the component itself and is variable.
  2. Component private: state belongs to the component itself, and can be modified internally through the setState method state.
  3. Purpose: Used to describe the state of a component and data that changes with user actions or over time.
  4. Initial value: Can be initialized in the constructor state and can be updated during the component's life cycle.

To summarize the differences:

  • propsIt is the data passed from the parent component to the child component. It is read-only and is used for data transfer between components.
  • stateIt is variable data managed internally by the component and used to describe the state and behavior of the component itself.

In React, props and state are important concepts of React components. Proper use of them can help you better manage component data and state to build maintainable and reusable components.

What are the two types of components in react?

In React, there are two main types of components:

1. Functional Components:

  • Features: A component defined in the form of a function that receives props and returns React elements.
  • Advantages: concise, easy to understand and write, and good performance.
  • Usage scenarios: Used for simple presentational components or components that purely display data, usually not involving state management or life cycle methods.
  • Example:
function FunctionalComponent(props) {
    
    
  return <div>{
    
    props.message}</div>;
}

2. Class Components:

  • Features: Component defined as an ES6 class, inherited from React.Component, with state and lifecycle methods.
  • Advantages: Has a complete life cycle, state management and more functions, suitable for complex logic and interaction.
  • Usage scenarios: Used for components that need to manage state, implement life cycle methods, or perform complex logic.
  • Example:
class ClassComponent extends React.Component {
    
    
  constructor(props) {
    
    
    super(props);
    this.state = {
    
     count: 0 };
  }

  render() {
    
    
    return (
      <div>
        <p>Count: {
    
    this.state.count}</p>
        <button onClick={
    
    () => this.setState({
    
     count: this.state.count + 1 })}>
          Increment
        </button>
      </div>
    );
  }
}

Hooks were introduced after React version 16.8, allowing functional components to also have state and the functions of other class components, allowing for more flexible handling of the state and life cycle within the component. Hooks can give functional components the capabilities of class components, so in modern React applications, the combination of functional components and Hooks has become the norm.

What is the difference between function components and ordinary components in react?

In React, "function components" usually refer to functional components (Functional Components), while "normal components" refer to class components (Class Components). There are some differences between these two component types:

Functional components (functional components):

  • Definition form: Defined in the form of a function, receiving props and returning React elements.
  • State management: It was not possible to directly manage the state before, but after the introduction of Hooks, it can be useduseState, useEffect Wait for the hook function to manage the state.
  • Lifecycle: Lifecycle methods cannot be used directly, but useEffect can be used to simulate part of the lifecycle behavior.
  • Performance: Generally better performance because there is no additional overhead of class components.

Ordinary components (class components):

  • Definition form: Defined in the form of an ES6 class, inherited from React.Component, with state and lifecycle methods.
  • State management: Manage status through this.state and this.setState().
  • Life cycle: You can use life cycle methods, such as componentDidMount, componentDidUpdate, etc.
  • Features: Has more features, such as this.props.children, getDerivedStateFromProps, etc. can be used.

choose:

  • Using functional components or normal components depends on your needs and personal preference.
  • If a component only needs to receive props and render content based on the props, you can use function components.
  • If a component needs to manage its own state, handle lifecycle, or contain complex logic, you can use ordinary components.

In modern React, the introduction of Hooks enables functional components to have the functions of state and other class components. Therefore, functional components can meet the needs in many scenarios and have been widely used because of their simplicity and performance advantages.

What did you do after setState in react?

]In React, setState is a method used to update component state (state). After calling setState, React does a series of things to update the component.

1. Update the component state object:

When calls setState, you can pass in an object or a function. When you pass in an object, React merges the object into the component's current state. When passed into a function, the function receives the current state as a parameter and returns a new state object.

2. Trigger component re-rendering:

setStateOnce called, React will trigger a re-rendering of the component. React will compare the difference between the new state and the previous state, find out the parts that need to be updated, and execute the rendering process.

3. Execute life cycle methods:

Before and after the component is re-rendered, React will execute a series of life cycle methods in sequence, such as shouldComponentUpdate, render, componentDidUpdate Wait. These methods allow you to perform some logic and do some preparation or cleanup before and after the update occurs.

4. Asynchronous updates and batch processing:

It is worth noting that setState does not change the state of the component immediately, but adds the update to a queue, and then performs batch updates at the appropriate time. This optimizes performance and avoids unnecessary multiple renderings.

5. Trigger sub-component updates:

If the state of the parent component changes, it may cause the child component to be re-rendered as well. React recursively updates the entire component subtree to ensure that the state of the component and the UI remain in sync.

In general, thesetState method triggers a series of update processes, including state updates, component re-rendering, and execution of life cycle methods. This mechanism in React ensures that changes in component state are correctly reflected in the user interface and can be updated efficiently while maintaining performance.

Redux is originally synchronous, why can it execute asynchronous code? What is the implementation principle of middleware?

Redux is indeed originally a synchronous state management library, but asynchronous operations can be implemented through middleware. Redux's middleware is an extension of the dispatch function, allowing additional functions to be added between dispatching actions and reducer execution, such as asynchronous operations, logging, exception handling, etc.

The implementation principle of asynchronous operation:

  1. Thunk Middleware: One of the commonly used middleware in Redux is Thunk Middleware. A Thunk is a function that defers the computation or execution of another function. It allows the action creation function to return not only an object but also a function. This function receives dispatch and getState as parameters, allowing us to perform asynchronous operations in the action.
  2. Implementation process: When an asynchronous action is dispatched, Thunk Middleware intercepts the action, determines that it is a function rather than an object, and then executes the function. Within the function body, you can perform asynchronous operations (such as initiating network requests), and wait for the asynchronous operation to complete before dispatching the real action.
  3. Dispatch after asynchronous completion: When the asynchronous operation is completed, call the dispatch method again to dispatch a new action. This new action will Processed by the reducer and updated application status.

How middleware works:

  1. Enhanced dispatch function: Middleware is actually an enhancement to the store.dispatch method. It receives an action and can process and modify this action. , or perform some additional operations.
  2. Chain call: Redux middleware can be connected in series to form a chain call process. Each middleware receives store.dispatch and store.getState as parameters and can execute customized logic before and after dispatching the action.
  3. Extended Redux functions: Middleware allows developers to add custom functions, such as asynchronous processing, logging, error handling, etc., without modifying the core logic of Redux.

Generally speaking, the principle of Redux middleware is to intercept and enhance the dispatch function, so that we can execute some custom logic before and after dispatching actions, thus realizing the expansion of asynchronous operations and other functions. Thunk Middleware is one of the commonly used middleware, which allows us to handle asynchronous logic in actions.

List the cases of re-rendering

In React, there are many situations when a component will re-render (triggering the render method). Here are some of them:

1. Component state changes:

  • React will re-render the component when its state is updated using setState .

2. Changes in properties (props):

  • The parent component is re-rendered, causing the props passed to the child component to change, and the child component will also be re-rendered.

3. Force re-rendering:

  • Call the forceUpdate() method to force the component to re-render.

4. Context changes:

  • When a component subscribes to the Context and the value of the Context changes, the component will re-render.

5. Use Hooks:

  • In functional components using Hooks, when the data relied on by hooks such as useState, useEffect, etc. changes, the component will be re-rendered.

6. Life cycle methods:

  • shouldComponentUpdateWhen in the true, the component will be re-rendered. lifecycle method returns

7. Other factors:

  • Changes in global state, routing changes, etc. may also cause components to be re-rendered.

In general, React will intelligently compare the changes in state and properties between the two renderings, and only update the changed parts to optimize rendering performance. Knowing when a re-render is triggered can help developers better optimize component performance and behavior.

React loads on demand

On-demand loading (also known as lazy loading) in React is an optimization technique used to lazily load components or other resources to improve application performance. React itself does not have built-in on-demand loading functionality, but it can be achieved through some methods.

Using React.lazy and Suspense:

  1. React.lazy: React provides the React.lazy function to dynamically load components. It allows you to use dynamic import to introduce components in the component tree and return a lazy-loaded component.

    const LazyComponent = React.lazy(() => import('./LazyComponent'));
    
  2. Suspense: Use the <Suspense> component to wrap the lazy-loaded component to display the loading indicator before the lazy-loaded component is loaded or Other content.

    <Suspense fallback={
          
          <div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
    

Combined with routing lazy loading:

Using route lazy loading can dynamically load relevant components in the application based on routes, which is usually used in conjunction with a routing library such as React Router.

import {
    
     lazy, Suspense } from 'react';
import {
    
     BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));

function App() {
    
    
  return (
    <Router>
      <Suspense fallback={
    
    <div>Loading...</div>}>
        <Switch>
          <Route exact path="/" component={
    
    Home} />
          <Route path="/about" component={
    
    About} />
          {
    
    /* Other routes */}
        </Switch>
      </Suspense>
    </Router>
  );
}

Implementation based on higher-order components or Hooks:

In addition to React.lazy and Suspense, you can also implement on-demand loading logic through custom high-order components (HOC) or custom Hooks. This method allows for more flexible control of component loading behavior.

On-demand loading can help reduce initial load times, especially for large apps or apps that need to load a large number of components, improving user experience and optimizing app performance.

React implements the directory tree (the component itself calls itself)

Components that implement directory trees can call themselves recursively to display the directory structure. Here is a simple example showing the structure of a directory tree:

import React from 'react';

const data = [
  {
    
    
    name: 'Folder 1',
    children: [
      {
    
    
        name: 'Subfolder 1.1',
        children: [
          {
    
     name: 'File 1.1.1' },
          {
    
     name: 'File 1.1.2' }
        ]
      },
      {
    
    
        name: 'Subfolder 1.2',
        children: [
          {
    
     name: 'File 1.2.1' }
        ]
      }
    ]
  },
  {
    
    
    name: 'Folder 2',
    children: [
      {
    
     name: 'File 2.1' },
      {
    
     name: 'File 2.2' }
    ]
  }
];

const TreeNode = ({
     
      node }) => (
  <div>
    <div>{
    
    node.name}</div>
    {
    
    node.children && node.children.map(child => (
      <div style={
    
    {
    
     marginLeft: '20px' }} key={
    
    child.name}>
        <TreeNode node={
    
    child} />
      </div>
    ))}
  </div>
);

const DirectoryTree = () => (
  <div>
    {
    
    data.map(rootNode => (
      <TreeNode key={
    
    rootNode.name} node={
    
    rootNode} />
    ))}
  </div>
);

export default DirectoryTree;

In this example, the data array represents the structure of the directory tree, and the TreeNode component is a recursive component that checks whether There are child nodes. If there are child nodes, continue to call itself to display the child nodes. The DirectoryTree component uses the root node in the data array to display the entire directory tree.

You can modify and extend this example according to your own data structure and needs to adapt to your directory tree display needs.

What are the three stages of the React component life cycle: loading, updating, and destruction?

In the life cycle of React components, it is usually divided into three stages: Mounting , Updating phase (Updating) andUnmounting phase (Unmounting). Each stage has specific lifecycle methods that allow you to perform specific actions during the component's different lifecycle stages.

Loading phase (Mounting):

  1. constructor: The component's constructor, called when creating a component instance, is used to initialize the state and bind event handling methods.
  2. static getDerivedStateFromProps: Called before rendering, used to update the state of the component based on the incoming props.
  3. render: Required lifecycle method, where the JSX structure of the component is rendered.
  4. componentDidMount: Called after the component is rendered for the first time. It is usually used to perform one-time operations, such as network requests, event subscriptions, etc.

Update phase (Updating):

  1. static getDerivedStateFromProps: Called after the loading phase and before each component update.
  2. shouldComponentUpdate: Called before the component is updated, allowing developers to control whether the component needs to be re-rendered. Returns true by default.
  3. render: Required lifecycle method, where the JSX structure of the component is rendered.
  4. getSnapshotBeforeUpdate: Called before updating the DOM, often used in conjunction with componentDidUpdate to capture the DOM state before the update.
  5. componentDidUpdate: Called after component update is completed, usually used to handle post-update operations, such as updating DOM, network requests, etc.

Unmounting phase (Unmounting):

  1. componentWillUnmount: Called before the component is unloaded (removed from the DOM), used to clean up side effects generated by the component, such as unsubscription, clearing timers, etc.

In addition, React version 17 has introduced new lifecycle methods getDerivedStateFromError and componentDidCatch, which are used to capture errors thrown by subcomponents in the component tree. , to help handle error conditions.

These life cycle methods provide the ability to execute logic at different stages, but it should be noted that as the React version is updated, some life cycle methods are marked as unsafe or deprecated. When writing components, you need to pay attention to follow the latest React ecosystem and documentation recommendations.

What operations does React do after calling this.setState? How to get the changed value?

When callingthis.setState, React will not immediately change the status value of the component. Instead, it will put the update into the queue, and then batch update the status at the appropriate time to improve performance.

The process of React processing setState:

  1. Merge state update: React will merge the state object passed when calling this.setState with the current state instead of directly replacing the entire state object.
  2. Batch update: React will collect all setState update operations, put them into the update queue, and then perform batch updates at the appropriate time . This process can reduce unnecessary repeated rendering and improve performance.
  3. Asynchronous update:setState The update does not take effect immediately, but is performed in an asynchronous environment. This means that after calling this.setState, the changed value cannot be obtained immediately.

How to get the changed value?

  1. Callback function:this.setState can receive the second parameter, which is a callback function that is called after the status is updated.

    this.setState({
          
           count: 1 }, () => {
          
          
      console.log('Updated state:', this.state.count); // 在回调函数中获取更新后的值
    });
    
  2. Life cycle method: You can get the updated value in the life cycle method, such as componentDidUpdate.

    componentDidUpdate(prevProps, prevState) {
          
          
      if (this.state.count !== prevState.count) {
          
          
        console.log('Updated state:', this.state.count); // 在 componentDidUpdate 中获取更新后的值
      }
    }
    

It should be noted that in functional components, you can use useState Hook to update the state, and you can directly obtain the updated state value. For example:

import React, {
    
     useState, useEffect } from 'react';

function ExampleComponent() {
    
    
  const [count, setCount] = useState(0);

  useEffect(() => {
    
    
    console.log('Updated state:', count); // 在 useEffect 中获取更新后的值
  }, [count]);

  // ...其他代码
}

After using useState Hook, the setCount update status method returns the updated status value, which can be directly passed count Variable gets the latest status.

What happens if I do setState three times

When setState is called three times in a row, React will batch the three status updates and merge the three updates into one update.

Batch update mechanism:

  1. Merge multiple setState: React will merge multiple consecutive setState operations into one update to avoid unnecessary repeated calculations and renderings.
  2. Asynchronous update queue: React will put the status update operation into the queue and batch process the updates in the queue at the appropriate time (usually at the end of the current JavaScript execution) operate.

Example:

this.setState({
    
     count: 1 });
this.setState({
    
     count: 2 });
this.setState({
    
     count: 3 });

In this example, although setState is called three times, React will merge these three update operations into one, and ultimately only one update operation will be performed. The final status is updated to { count: 3 }.

Precautions:

  1. Use setState in functional form: If the parameter of setState is a function, then this function will receive the previous state as a parameter, which can guarantee updates It is based on the latest status.

    this.setState(prevState => ({
          
           count: prevState.count + 1 }));
    this.setState(prevState => ({
          
           count: prevState.count + 1 }));
    this.setState(prevState => ({
          
           count: prevState.count + 1 }));
    

    In this example, each time setState is updated based on the previous state, and the end result is that the state value is increased by 3.

  2. The behavior of setState in class components and functional components is slightly different: In class components, calling multiple times in successionsetState will perform batch updates , and when using multiple useState hooks to update in a functional component, each setState will independently trigger the component to re-render.

Will the setState component always be re-rendered if it is executed in a loop? Why?

React will optimize the continuous loop execution of setState and will not cause the component to be infinitely re-rendered. React will merge consecutive setState calls and perform only one update to improve performance.

Combine consecutive setState calls:

  1. Batch update: React will merge multiple setState calls into one update. This batch update mechanism avoids multiple unnecessary calls. Component rendering.
  2. Asynchronous update queue: React batches the update queue at the right time (usually at the end of the current JavaScript execution), thus avoiding frequent rendering operations.

Example:

// 循环调用 10 次 setState
for (let i = 0; i < 10; i++) {
    
    
  this.setState({
    
     count: i });
}

In this example, even if the loop is called 10 timessetState, React will merge these 10 update operations into one update. In the end, only one update operation will be performed, rendering the final status value.

Precautions:

  1. Update based on the previous state: If the parameter of setState is a function, the function will receive the previous state as a parameter, which ensures the update It is based on the latest status.

    for (let i = 0; i < 10; i++) {
          
          
      this.setState(prevState => ({
          
           count: prevState.count + i }));
    }
    

    In this example, each update is based on the previous state, and the final state value is the result of continuous accumulation.

  2. Behavior in functional components: In functional components, if multiple useState hooks are called multiple times for updates, each a>useState will trigger the component to re-render.

The process of rendering a react component

The rendering process of React components is an important process, which involves the creation, update and final DOM rendering of virtual DOM. The following is the main process of React component rendering:

1. Create virtual DOM:

  1. Component rendering trigger: When the component's state (state) or properties (props) change, or when the component is mounted for the first time, React will trigger the re-rendering of the component.
  2. Call the render method: React calls the component's render method to generate the virtual DOM structure (Virtual DOM) corresponding to the component.

2. Compare the virtual DOM before and after:

  1. Diff algorithm: React uses Virtual DOM to describe the structure of the real DOM tree. When updating, React will compare the two virtual DOM trees before and after to find the changed parts.
  2. Generate update plan: After comparison, React will generate an update plan to determine the specific operations that need to be performed on the real DOM.

3. Apply updates:

  1. Application update plan: React will convert the changed parts into real DOM operations (add, delete, modify, move nodes, etc.) according to the update plan, and apply it to the browser The actual DOM tree in .
  2. DOM update: React applies updates to the real DOM to implement changes to the user interface.

4. Complete the update:

  1. Life cycle method: If the relevant life cycle method is triggered when the component is updated, such ascomponentDidUpdate, React will call these methods to perform corresponding operations. .
  2. Repeat process: When the state or properties of the component change again, React will retrigger the rendering process and repeat the above steps.

Summarize:

The rendering process of React components mainly includes the stages of creating virtual DOM, comparing virtual DOM, and applying updates to real DOM. React improves performance by using virtual DOM and optimization algorithms, updating only the parts that need to change, thus minimizing operations on the real DOM and improving page rendering efficiency.

Guess you like

Origin blog.csdn.net/wsq_yyds/article/details/134891209
Recommended