Fine-grained state response system, method and application between React components based on Proxy and dependency injection

Through the React component state response system based on Proxy and dependency injection, the problems of coarse update granularity, high performance overhead, and complex dependency management in state communication and dynamic rendering between React components are solved, automatic dependency management and precise state updates of components are realized, and rendering performance and development efficiency are improved.

CN120407051BActive Publication Date: 2025-09-12JIANGSU OPEN UNIVERSITY (THE CITY VOCATIONAL COLLEGE OF JIANGSU)
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202510919050.8
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2025-07-04
Publication Date
2025-09-12
Estimated Expiration
2045-07-04

AI Technical Summary

Technical Problem

Existing state communication and dynamic rendering between React components have problems such as coarse update granularity, high performance overhead, and complex dependency management. Especially when the component structure is complex and the dependency relationships are diverse, it is difficult to automatically and accurately track the specific dependencies of the components on the state and only update the components that are truly affected.

Method used

It adopts a fine-grained state response system between React components based on Proxy and dependency injection, and realizes automatic dependency management and precise state updates between components through a centralized observable state storage module, automatic dependency tracking and registration module, precise state change notification and target update trigger module, and component dependency injection and connection module.

Benefits of technology

It implements extremely fine-grained component updates, reduces unnecessary DOM operations, improves rendering performance, simplifies component logic, improves development efficiency, and provides automated and easy-to-integrate state management.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120407051B_ABST
    Figure CN120407051B_ABST
Patent Text Reader

Abstract

The present invention provides a fine-grained state response system, method, and application between React components based on Proxy and dependency injection, relating to the field of computer front-end development. The system includes a centralized observable state storage module for storing globally shared state, an automatic dependency tracking and registration module integrated into the Proxy's get interceptor, a precise state change notification and target update triggering module integrated into the set interceptor, and a component dependency injection and connection module. Based on Proxy's automatic dependency tracking, the system is capable of accurate tracking down to the specific property path level of state objects. A component is re-rendered only when the smallest state unit it actually depends on changes, minimizing unnecessary DOM operations and improving performance in frequent update scenarios.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the field of computer front-end development, and in particular to a fine-grained state response system between React components based on Proxy and dependency injection, a method and an application thereof. Background Art

[0002] As the current mainstream front-end development framework, React's component-based approach has greatly improved development efficiency and code maintainability. However, in complex application scenarios, state sharing and data communication between multiple components often become particularly complex.

[0003] There are several ways to communicate data between existing React components:

[0004] 1. Props transfer: The parent component passes data and callback functions to the child component. For components with a deeper hierarchy or components that are not parent-child relationships, data needs to be passed between components layer by layer, resulting in lengthy and difficult-to-maintain code.

[0005] 2. Context API transfer: Native React has a way to transfer data across layers, avoiding the need to pass data between components. However, Context updates are usually broadcast. When the Context value changes, all components that consume the Context may trigger full rendering of the data, even if they only use a portion of the unchanged data. This may cause performance issues in large applications or scenarios with frequent data updates.

[0006] 3. State management libraries, such as Redux, Zustand, and Jotai: React's component state management method uses selectors to allow components to subscribe to the state fragments they care about. This optimizes the efficiency of data communication and updates to a certain extent, but the writing and maintenance of selectors and the accuracy of dependencies still need to be maintained manually, and the granularity of data updates is still not fine enough.

[0007] 4. Hooks-based delivery: By using Hooks such as useEffect and useMemo, specific state monitoring and linkage logic between components can be combined. However, this method requires manual management of the dependency array, which is prone to missing dependencies or including unnecessary dependencies. In addition, the logic is scattered across various components, and the ability to accurately and automatically respond to global states in a fine-grained manner is limited.

[0008] When implementing responsive updates for multiple distributed components, these methods often suffer from inefficiencies, unnecessary rendering due to overly wide update scopes, complex implementation logic, and difficulties in dependency management. Especially when component structures are complex and dependencies are diverse, automatically and accurately tracking the specific dependencies of components on state and updating only the components truly affected by state updates presents a pressing technical challenge. Summary of the Invention

[0009] Purpose of the invention: In response to the problems of coarse update granularity, high performance overhead, and complex dependency management in the state communication and dynamic rendering between React components in the existing technology, the present invention proposes a fine-grained state response system, method and application between React components based on Proxy and dependency injection, which can automatically and accurately identify and update only the components that depend on the specific part of the changed state when the state changes, thereby improving rendering performance and development efficiency.

[0010] In a first aspect of the present invention, a fine-grained state response system between React components based on Proxy and dependency injection is proposed, the system comprising:

[0011] A centralized observable state storage module is used to store globally shared states. It uses a proxy to deeply proxy state objects and intercept attribute read and write operations. It also maintains a dependency mapping table to record the mapping relationship between state paths and subscribed component instances.

[0012] The dependency automatic tracking and registration module is integrated into the Proxy's get interceptor. When the component is rendered, it reads the state attribute, automatically captures the access, and registers the component instance and the exact path of the accessed attribute into the dependency map.

[0013] The module for precise notification of state changes and triggering target updates is integrated into the set interceptor of the Proxy. When a state property is modified, it captures the write operation and searches for component instances that depend on the path according to the dependency mapping table, triggering their updates.

[0014] The component dependency injection and connection module establishes a connection between the component and the state storage and declares the dependency intention through the hook function, registers the dependency when the component is mounted, and cleans up the subscription records in the dependency mapping table when it is uninstalled.

[0015] Optionally, the centralized observable state storage module includes:

[0016] Deep proxy function, used to recursively proxy each property of the state object and generate a Proxy instance containing the complete path;

[0017] The dependency map uses a dot-separated string path as a key and stores a collection of component instances that subscribe to the path.

[0018] Optionally, the implementation of the depth proxy function includes:

[0019] When reading the attribute value as an object, recursively call the deep proxy function and pass in the current path array to generate a nested Proxy;

[0020] In the get interceptor, register the current rendering component instance and access path to the dependency mapping table.

[0021] Optionally, the implementation of the dependency automatic tracking and registration module includes:

[0022] In the get interceptor, concatenate the currently accessed attribute name into a full path array and convert it into a dot-separated path key;

[0023] If there is a currently rendered component, call the dependency tracking algorithm to register the component instance and path key to the dependency map.

[0024] Optionally, the implementation of the state change precise notification and target update triggering module includes:

[0025] In the set interceptor, compare the old and new property values ​​and trigger notification only when the value changes;

[0026] Find the dependent component set copy according to the modification path, and call the forceUpdate method of the component to force it to re-render.

[0027] Optionally, the component dependency injection and connection module includes:

[0028] The useReactiveState hook function is used to generate a unique component ID, establish a connection with the state store, and set the global current rendering component context when the component is rendered;

[0029] The dependency cleanup algorithm traverses the dependency mapping table when the component is uninstalled and removes all subscription records of the component.

[0030] The second aspect of the present invention discloses a method for fine-grained state response between React components based on Proxy and dependency injection. The method relies on the system disclosed in the first aspect above for implementation and includes the following steps:

[0031] Step 1: Create the state object of the deep proxy through the centralized observable state storage module and maintain the dependency mapping table;

[0032] Step 2: When the component is rendered, the component instance and the accessed state path are registered in the dependency mapping table through the dependency automatic tracking and registration module;

[0033] Step 3: When the state attribute is modified, the state change precise notification and target update trigger module trigger the update of related components according to the dependency mapping table;

[0034] Step 4: Implement the connection between components and state storage and dependency declaration through component dependency injection and connection modules, and clean up dependency records during uninstallation.

[0035] Optionally, step 1 further includes: defining initial state data, recursively generating a Proxy instance through a deep proxy function, and generating a path key containing a complete path when each attribute is accessed.

[0036] Optionally, step 2 further includes: in the get interceptor of the Proxy, capturing the component's access to the state attribute, and registering the current rendering component instance and the path key in the dependency mapping table.

[0037] Optionally, step 3 further includes: in the set interceptor of the Proxy, comparing the new and old attribute values, searching for the dependent component according to the path key only when the value changes, and calling the forceUpdate method of the component.

[0038] Optionally, step 4 further includes: generating a unique component ID through the useReactiveState hook function, setting the current rendering component context when the component is mounted, and clearing subscription records in the dependency mapping table when the component is uninstalled.

[0039] A third aspect of the present invention discloses applications of the above-mentioned fine-grained state response system between React components based on Proxy and dependency injection, including any one of the following applications:

[0040] Application of shopping cart components in e-commerce scenarios;

[0041] Application of inventory mutual exclusion in e-commerce scenarios;

[0042] Application of real-time modification of products in e-commerce scenarios.

[0043] In a fourth aspect of the present invention, a computer-readable storage medium is disclosed, wherein the storage medium stores at least one executable instruction. When the executable instruction is run on an electronic device, the electronic device executes the fine-grained state response method between React components based on Proxy and dependency injection disclosed in the second aspect.

[0044] Compared with the prior art, the technical solution of the present invention has the following beneficial technical effects:

[0045] (1) Ultra-fine-grained updates: Proxy-based automatic dependency tracking can be accurate down to the specific property path level of the state object. A component will only be re-rendered when the smallest state unit that the component actually depends on changes, minimizing unnecessary DOM operations and significantly improving system performance, especially in scenarios where the state objects are large, complex, or frequently updated.

[0046] (2) Automatic dependency management: Developers do not need to manually maintain the useEffect dependency array. Dependencies are automatically established and updated when the component renders and accesses the state, reducing errors caused by improper dependency management, such as missing dependencies leading to state synchronization or including irrelevant dependencies leading to performance degradation.

[0047] (3) Simplify component logic: Encapsulate the complex logic of state subscription and update triggering within the system. Components only need to declare dependency intentions and directly read and write state, making component code more concise and more focused on business logic.

[0048] (4) Improve development experience: Automation and precision make state management more intuitive and easier to debug.

[0049] (5) Easy to integrate: It can be introduced as a plug-in or library for existing React applications and combined with TypeScript to provide good type support. BRIEF DESCRIPTION OF THE DRAWINGS

[0050] Figure 1 This is a flowchart of fine-grained state response between React components based on Proxy and dependency injection in the embodiment. DETAILED DESCRIPTION

[0051] In the following description, numerous specific details are provided to provide a more thorough understanding of the present invention. However, it will be apparent to those skilled in the art that the present invention may be practiced without one or more of these details. In other instances, certain technical features well known in the art have not been described to avoid confusion with the present invention.

[0052] This embodiment discloses a fine-grained state response system between React components based on Proxy and dependency injection, as well as a complete construction method for this system. This invention systematically combines the automatic fine-grained dependency tracking capabilities of Deep Proxy with the connection mechanism of React components, such as using HOCs and Hooks, to form a complete, automated, and responsive update method and system architecture with accurate property paths. This system is applied to front-end applications based on React and TypeScript. The specific construction process is as follows:

[0053] Step S1: Define the Centralized Observable StateStore Module. This module is responsible for storing the component's globally shared state. The component's core state object is deeply proxied through this module's proxy, which intercepts read and write operations on the state object's properties. This module maintains a dependency map that records the path of each specific property of the state object, such as user, user.name, and user.email, and its mapping to the component instances subscribed to that path.

[0054] Step S2: Define the Dependency Auto-Tracking and Registration Module, which is integrated into the Proxy's get interceptor. When a component with injected dependencies first reads a property of the Proxy's state object during rendering, the module automatically captures this access and registers the current component instance and the exact path to the accessed property in the dependency mapping table. This eliminates the need to manually maintain a dependency array like with useEffect, such as: useEffect(() =>{…},[page, pageSize, sort, sortOrder,formQuery]);

[0055] Step S3: Define the Precise State Change Notification and Targeted Update Trigger Module, which is integrated into the proxy's set interceptor. When a property of a state object is modified, this module captures the write operation. Based on the path of the modified property, it searches the dependency mapping table for all component instances that have registered dependencies on that path or its parent path. Update signals are then sent only to these precisely identified component instances.

[0056] Step S4: Define the Component Dependency Injection and Connection Module. This module is responsible for establishing a connection to the state store through the useReactiveState hook function when the component is mounted and declaring dependency intent, such as whether to access user, user.name, or user.email. When the component is unmounted, it automatically cleans up all subscription records in the dependency map. This module also provides interfaces for components to access and modify data in the state store.

[0057] As a preferred embodiment, the following specific steps can be taken to implement step S1.

[0058] Step S1.1: Create a centralized observable state storage module.

[0059] Define the initial state data initialState of the application. The initial state data contains user object and cart object. For example: initialState{user:{id:1,name:'张三',email:'zhangsan@example.com'},cart:{items:[{productId:'prod001',productName:'笔记本',quantity:1,price:688},{…}]},total:799}.

[0060] Step S1.2: Define the type of component instance, which can be the unique identifier of a class component or a function component. The method is: type ComponentInstance = React.Component | { _id: number; _update: (val:number) =>void};

[0061] Step S1.3: Define the type of state path, which is a string. The method is: type StatePath =string;

[0062] Step S1.4: Define a variable currentRenderingComponent to track the currently rendering component instance, CRC - Current Rendering Component. The method is: let currentRenderingComponent: ComponentInstance | null = null;

[0063] Step S1.5: Create an observable state storage instance createObservableStore. The input parameter is the initial state data initialState, and the return is an object mutations containing the proxied state state and the method to modify the state. The method is: function createObservableStore<T extends object>(initialState: T){…}

[0064] Step S1.6: Create a deep proxy function deepProxy in the state storage instance createObservableStore. The input parameters are the object obj to be proxied and the path array path of the current object in the overall state tree. Return the proxied object. The method is: function deepProxy<O extends object> (obj: O,path: StatePath[]): O {…}

[0065] Step S1.7: Use the deepProxy function in the state storage instance createObservableStore to deeply proxy the initial state object initialState. The input parameters are the initial state data initialState and the initial path, which defaults to an empty array. The method is: const state = deepProxy(initialState,[]);

[0066] Step S1.8: Create a new React native Proxy in the deep proxy function deepProxy and create a new Proxy instance for the current object using the method return new Proxy(obj, {…}).

[0067] Step S1.9: Create a get interceptor and record the current rendering component's dependency on the current path key.

[0068] A. Create a get interceptor for the obj object in Proxy, which is triggered when reading the object's properties. The method is: get(target, prop, receiver) {…}.

[0069] B. Define a path variable array, currentPathArray, and add the name of the currently accessed property (prop) to the path array, forming a complete path array for the current property, such as [user], [user,name], and [user,email]. The method is: const currentPathArray = path.concat(String(prop));

[0070] C. Define a path key pathKey and convert the path array currentPathArray into a dot-separated string path key pathKey, such as user, user.name, and user.email, using the following method: const pathKey = currentPathArray.join('.').

[0071] D. If there is a component currently being rendered, call the dependency tracking algorithm trackDependency in the "Dependency Automatic Tracking and Registration Module" to record the dependency of the current rendering component on the current path key. The input parameters are the current rendering component currentRenderingComponent and the path key pathKey. The method is: if (currentRenderingComponent) { trackDependency(currentRenderingComponent,pathKey )};

[0072] E. Define a variable value to store the original property value of the target object obtained. The method is const value = Reflect.get(target, prop, receiver).

[0073] F. If the attribute value of value is an object and is not empty, recursively create and return a new Proxy for the attribute value object using currentPathArray as a parameter and pass in the new path. currentPathArray is the array path of the current object, such as [user], [user,name], [user,email], which can be understood as recursively proxying each attribute in the object. The method is: if (typeof value === 'object') {return deepProxy(value,currentPathArray)};

[0074] G. Finally, return the proxied object using the return value method.

[0075] Step S1.10: Create a set interceptor and modify the property value of the target object, and at the same time call the change notification algorithm to notify all components that depend on the path key to update.

[0076] A. Write a set interceptor for the obj object in Proxy, which is triggered when the object properties are modified. The method is: set(target, prop, value, receiver){…}.

[0077] B. Define a path variable array currentPathArray, add the currently accessed property name (prop) to the path array currentPathArray to form a complete path array of the current property, such as [user], [user,name], [user,email], the method is: const currentPathArray = path.concat(String(prop));

[0078] C. Define a path key pathKey and convert the path array currentPathArray into a dot-separated string path key pathKey, such as user, user.name, and user.email, using the following method: const pathKey = currentPathArray.join('.').

[0079] D. Define a variable previousValue to store the object property value before the object is modified. The method is: const previousValue = Reflect.get(target, prop, receiver);

[0080] E. Compare the object property value before modification (previousValue) with the new value to be modified. If the new value is the same as the old value (use Object.is for strict comparison), no action is performed and true is returned directly to indicate that the modification is successful (but no actual change is made). The method is: if (Object.is(previousValue, value)) return true;

[0081] F. Define a variable named result to store the modified object property value. If the new value is different from the old value, use Reflect.set to modify the target object's property value and store it in result. At the same time, get the result of whether the operation is successful. The method is: const result = Reflect.set(target,prop,value,receiver);

[0082] G. If the modification operation is successful, call the change notification algorithm notifyChange in the "State Change Precise Notification and Target Update Trigger Module" to notify all components that depend on the path key to update. The method is as follows: if (result) {notifyChange(pathKey)};

[0083] H. Finally, return the proxied object (the result of the modification operation) using the return result method.

[0084] Step S1.11: Create predefined methods called Mutations in the state store instance createObservableStore for modifying the state. These methods allow external callers to directly operate on the proxied state object, thereby automatically triggering the Proxy's set interceptor. The method is: const mutations = {…};

[0085] A. Create a method to modify user attributes in the Mutations method: updateUserName(newName: string): void { (state as AppState).user.name = newName}:

[0086] B. Create the addItemToCart method in the Mutations method. The method is: addItemToCart(item: {productId: string; productName: string; quantity:number}): void {…}

[0087] Step S1.12: Return an object containing the proxied state object (state) and methods for modifying the state (mutations). The method is: return { state: state as T, mutations}.

[0088] As a preferred embodiment, the following specific steps may be taken to implement step S2.

[0089] Step S2.1: Create a dependency automatic tracking and registration module

[0090] Create a dependency tracking algorithm, Algorithm 1:Dependency Tracking, the method is: functiontrackDependency(componentInstance: ComponentInstance, path: StatePath): void{…}, the input parameter componentInstance is the currently rendered component instance, and StatePath is the state path.

[0091] Step S2.2: Automatic Dependency Tracking. In the get interception of the observable state storage module in step S1.9, the currently rendered component instance, currentRenderingComponent, and the path key, pathKey, are passed as parameters to the dependency tracking algorithm, trackDependency. After parameter name conversion by the dependency tracking algorithm, the currently rendered component instance is named ComponentInstance within the method, and the component path is named path.

[0092] Step S2.3: Automatic dependency. Define a collection dependents to store the existing dependent component collection of the current path obtained from the dependency map table. The method is: let dependents = dependencyMap.get(path);

[0093] Step S2.4: Determine whether there is a dependency. If no component depends on the path, create a new Set to store the components that depend on the path. The method is: if (!dependents) { dependents = new Set()}.

[0094] Step S2.5: Register the path first, method: dependencyMap.set(path, dependents);

[0095] Step S2.6: Register the component again and determine if the current component instance has not been recorded as a dependent of the path. Then add the current component instance to the dependency set of the path. The method is: if (!dependents.has(componentInstance)) { dependents.add(componentInstance)}.

[0096] As a preferred embodiment, the following specific steps may be taken to implement step S3.

[0097] Step S3.1: Accurate notification of state change and target update trigger module

[0098] Create a change notification algorithm, Algorithm 2: Change Notification, with the following method: function notifyChange(path: StatePath): void {…}, where the input parameter StatePath is the state path to be modified.

[0099] Step S3.2: Accurately notify the state change. In the set interception in the observable state storage module in step S1.10, the path key pathKey of the currently modified component instance is passed as a parameter to the trackDependency change notification algorithm. After the parameter name conversion in the change notification algorithm, the path name of the currently modified component instance is called path within the method.

[0100] Step S3.3: Define a collection dependents to store the component set that depends on the path obtained from the dependency map table. The method is: const dependents = dependencyMap.get(path);

[0101] Step S3.4: Determine whether there is a dependency. If so, create a copy of the dependent component set to prevent the set from being modified during subsequent traversal due to reasons such as component uninstallation. Method: if(dependents&&dependents.size>0) { const notifySet = new Set(dependents)};

[0102] Step S3.5: Target update trigger. Traverse the dependent component set replica notifySet, traverse each dependent component instance in the replica notifySet, and call the triggerUpdate function one by one to notify the component to update. The method is: notifySet.forEach((componentInstance) =>{ triggerUpdate(componentInstance)};

[0103] Step S3.6: Dependency target update.

[0104] A. Create a function triggerUpdate to trigger component update. The input parameter is the component instance componentInstance that needs to be updated. The method is: function triggerUpdate(componentInstance:ComponentInstance): void {…};

[0105] B. Check whether the component instance componentInstance is a React class component and whether the forceUpdate method exists on its instance. The method is: if ( componentInstance instanceof React.Component&&typeof componentInstance.forceUpdate === 'function') {…}

[0106] C. Trigger component update. Call the forceUpdate method of the class component to force it to re-render: componentInstance.forceUpdate().

[0107] As a preferred embodiment, the following specific steps may be taken to implement step S4.

[0108] Step S4.1: Create component dependency injection and connection modules

[0109] Export the global observable storage instance store so that the component connection module can connect to the store. The parameter is the initial state data initialState of the application. The method is: export const store = createObservableStore(initialState);

[0110] Step S4.2: Create a connection module method function useReactiveState, which is used to connect the function component to the observable storage instance so that it can respond to state changes and automatically re-render. The method is: export function useReactiveState() {…};

[0111] Step S4.3: Create a component update mechanism. Use useState to create a state and its update function. Obtain the forceUpdate function to force the component to re-render when needed. The method is: const [, forceUpdate] = useState(0);

[0112] Step S4.4: Assign a unique component identifier. Use useMemo to generate an ID that remains unique throughout the component's lifecycle. Use nextComponentId++ to ensure that each Hook call (i.e., each component instance) has a different ID. The method is: const componentId = useMemo(() =>nextComponentId++, []);

[0113] Step S4.5: Create a stable component reference. Use useRef to create a stable reference (componentRef) that persists across multiple component renders. This reference object contains the component's unique ID (_id) and its update function (_update). The .current property ensures that even if the component is re-rendered, the reference is still to the same object. The method is: const componentRef = useRef({ _id: componentId, _update: forceUpdate}).current;

[0114] Step S4.6: Set up the rendering context. Before component rendering begins, save a reference to the previously rendered component (previousCRC) using the following method: const previousCRC = currentRenderingComponent. Set the component instance where the current Hook is located, componentRef, to the global currentRenderingComponent. This way, during the current component rendering, any access to the proxy state will register this componentRef as a dependency. The method is: currentRenderingComponent = componentRef;

[0115] Step S4.7: Restore the rendering context. Check again whether the global CRC is still the current component. If so, restore the CRC after rendering is complete by: if (currentRenderingComponent === componentRef) {currentRenderingComponent = previousCRC};

[0116] For example: Component A starts rendering and sets currentRenderingComponent = A; during the rendering process of component A, subcomponent B is rendered; component B starts rendering, and at this time, it is necessary to first save previousCRC = A; then set currentRenderingComponent = B; after B rendering is completed, it is necessary to restore currentRenderingComponent = previousCRC (i.e. A).

[0117] Step S4.8: Create the return object of the connection module method function useReactiveState, and return the current state state obtained from the global storage instance store and the mutations object for modifying the state. The method is: return { state: store.state, mutations: store.mutations};

[0118] Step S4.9: Component connection. There is an existing UserProfile file. Define the functional component UserProfile() {...} in the file. Define the state state and the mutations object for modifying the state in the functional component. The method is: const { state, mutations} = useReactiveState(). In this way, the global storage instance store can be connected through the useReactiveState function, and the current state of the component and the method for modifying the state can be accessed.

[0119] Step S4.10: Dependency injection and dependency intention declaration of the component. When accessing user-specific data from the global state state, such as accessing the user name through the method const userName = state.user.name, declare the dependency intention. When accessing state.user.name, the dependency tracking algorithm will automatically run, and register the UserProfile functional component as a dependency of the user.name path, realizing automatic injection of dependencies.

[0120] Step S4.11: Provide an interface component. Create a handleUpdateName function in the UserProfile functional component to modify the user name. The method is: handleUpdateName = () => { const newName = '李四'}. The handleUpdateName function modifies the user name by calling the mutations.updateUserName(newName) method of the mutations object in the storage instance store. At the same time, this will trigger the set interceptor of the Proxy, and the change notification algorithm will automatically run for the user.name path, causing the UserProfile component to re-render.

[0121] Step S4.12: Clean up the dependency mapping table when the component is unloaded.

[0122] A. Create a dependency cleanup algorithm (Algorithm 3: Dependency Cleanup) with the method: function cleanupDependencies(componentInstance: ComponentInstance): void {…}, where the input parameter is the component instance componentInstance to be unloaded.

[0123] B. Traverse each entry in the dependency map, including the path and the set of components depending on that path, with the method: dependencyMap.forEach((dependents, path) => {...});

[0124] C. If the current component instance exists in the set of dependent components for this path, then remove the current component instance from the set of dependent components for this path, with the method: if (dependents.has(componentInstance)) { dependents.delete(componentInstance)};

[0125] D. Hook componentRef through the useEffect hook function in the connection module method function useReactiveState, and automatically call the dependency cleanup algorithm when the component is unloaded, passing in the current component instance to remove all its dependency records. The method is: useEffect(() => { return () => { cleanupDependencies(componentRef)}}, [componentRef]).

[0126] The following shows a fine-grained state response example between components with Proxy and dependency injection when the user user and cart shopping cart perform complex operations.

[0127] const initialState: AppState = { user: { id: 1, name: 'Zhang San (initial name)', email: 'zhangsan@example.com'}, cart: { items: [{ productId: 'prod001', productName: 'High-performance laptop', quantity: 1, price: 7999}, { productId: 'prod002', productName: 'Wireless mechanical keyboard', quantity: 2, price: 499}], total: 7999 + 2 * 499, / / Initial total price}};

[0128] The existing initial state data initialState includes the user object user and the shopping cart object cart, and these two objects have been initialized and assigned values. The two React files UserProfile.tsx and ShoppingCart.tsx are now connected to the "centralized observable state storage module" through the "dependency injection and connection module". When operating the user object and the shopping cart object, the Proxy deep proxy is used to achieve fine-grained state response between components. In the process of the embodiment, it is possible to observe the fine-grained state response between components, the automatic injection process of the dependency path and component instance in the dependency mapping table, and the precise notification and targeted update of state changes after the component changes. The principle of the present invention can be further understood through examples.

[0129] Step 1: Component connection and dependency declaration.

[0130] Step 1.1: Import the useReactiveState function from the Component Dependency Injection and Connection Module into both UserProfile.tsx and ShoppingCart.tsx files, using the import { useReactiveState} from '. / observableStore' function.

[0131] Step 1.2: Define the global state and mutations objects in two files, respectively, using const {state, mutations} = useReactiveState(). This allows both files to connect to the global store instance store through the useReactiveState function, allowing them to access the global state in the store instance and manipulate the user and cart objects through methods in the mutations object.

[0132] Step 1.3: Dependency declaration of the UserProfile function component. Define const userName = state.user.name; const userEmail = state.user.email in the UserProfile function, indicating that the UserProfile function component wants to access the user.name and user.email of the user object.

[0133] Define the handleUpdateName method in the UserProfile function to modify the user name.

[0134] const handleUpdateName = () =>{

[0135] const newName = `Li Si (renamed to ${new Date())}`;

[0136] mutations.updateUserName(newName);};

[0137] Step 1.4: Dependency declaration for the ShoppingCart function component. Define const cartItems = state.cart.items; const cartTotal = state.cart.total in the ShoppingCart function, indicating that the ShoppingCart function component wants to access cart.items and cart.total of the cart object.

[0138] Define the handleAddItem method in the ShoppingCart function, which is implemented by calling the addItemToCart method of the mutations object in the global storage to add random items to the shopping cart.

[0139] const handleAddItem = () => {

[0140] const newItemId = `prod${Date.now().toString()}${Math.floor(Math.random()*100)}`;

[0141] const newItemName = `New Item) ${Math.floor(Math.random() *1000)}`;

[0142] const newItemPrice = Math.floor(Math.random() * 200) + 50;}

[0143] Step 2: Component rendering and dependency tracking

[0144] Step 2.1: Component rendering.

[0145] Import the UserProfile.tsx and ShoppingCart.tsx files into App.tsx, with App as the main application. Then run app.tsx. This will cause the UserProfile and ShoppingCart components to run and initialize in the app. These two components will each generate a unique ID for their lifecycle using useMemo and nextComponentId++, as defined in step S4.4. The generated ID for the UserProfile component is UserProfile(id:0), and the ID for the ShoppingCart component is ShoppingCart(id:1). These two component IDs will be registered in the dependency mapping table by the subsequent dependency tracking algorithm.

[0146] Step 2.2: Component tracing.

[0147] A. The dependency intention of the UserProfile function is to access the user.name and user.email of the user object. Therefore, the object that needs to be proxied by Proxy is the user object. When the user object enters the deep proxy function deepProxy, it is intercepted by Proxy's get trap. The dependency tracking algorithm registers three dependency paths in the dependency mapping table: user, user.name, and user.email. Then, the dependent component UserProfile (id: 0) is registered three times in the dependency mapping table according to the dependency path.

[0148] B. The ShoppingCart function's dependency intent is to access the cart object's cart.items and cart.total. Therefore, the object to be proxied is the cart object. When the cart object enters the deepProxy function, it is intercepted by the Proxy's get trap. The dependency tracking algorithm then registers three dependency paths in the dependency mapping table: cart, cart.items, and cart.total. The dependent component ShoppingCart (id: 1) is then registered three times in the dependency mapping table based on the dependency paths. See Table 1 below for the records in the dependency mapping table.

[0149] Table 1: DependencyMap dependency mapping table

[0150]

[0151] Step 3: State Change, Change Capture, and Accurate Notification

[0152] A. Run the handleUpdateName method in the UserProfile function to modify the user name. The handleUpdateName method calls the updateUserName method of the mutations object in the global observable storage instance store to modify the user name to 'Li Si'. The method is: mutations.updateUserName(newName);

[0153] At this time, the modification of user.name is captured by the set trap of Proxy. The change notification algorithm finds the UserProfile(id:0) component that depends on user.name in the dependency mapping table, and calls the triggerUpdate function to notify the UserProfile(id:0) component to update.

[0154] B. Run the handleAddItem method in the ShoppingCart function to add a shopping cart. The handleAddItem method calls the addItemToCart method of the mutations object in the global observable storage instance store to add items to the shopping cart one by one. The method is: mutations.addItemToCart({ productId: newItemId, productName:newItemName, quantity: 1, productName: newItemName, price: newItemPrice,});

[0155] At this time, the modification of cart.item is captured by the set trap of Proxy. The change notification algorithm finds the ShoppingCart(id:1) component that depends on cart.item in the dependency mapping table, and calls the triggerUpdate function to notify the ShoppingCart(id:1) component to update.

[0156] Step 4: Targeted Updates

[0157] The system only sends update signals to the components found in step 4, triggering re-rendering of these components. For example, other components that do not depend on user.name will not be triggered to update even if they are also connected to the state store or depend on other parts of the state, such as store.state.cart.items.

[0158] Step 5: Component uninstallation and cleanup

[0159] The global state store hooks the caller's componentRef through the useEffect hook function. When the component is uninstalled, the dependency cleanup algorithm is automatically called, passing the current component instance and removing all its dependency records. The method is: useEffect(() =>{ return () =>{ cleanupDependencies(componentRef)}}, [componentRef]).

[0160] An embodiment of the present application also provides an electronic device, which includes a processor and a memory storing computer program instructions; when the processor executes the computer program instructions, it implements the various functions or steps performed in the above method embodiment, which are not described in detail here.

[0161] An embodiment of the present application also provides a computer-readable storage medium, which includes computer instructions. When the computer instructions are executed on the above-mentioned electronic device, the electronic device executes the various functions or steps executed in the above-mentioned method embodiment, which will not be repeated here.

[0162] The embodiment of the present application further provides a computer program product. When the computer program product is run on a computer, the computer is enabled to execute the various functions or steps executed in the above method embodiment, which will not be described in detail here.

[0163] The various embodiments of the mechanisms disclosed in this application can be implemented in hardware, software, firmware, or a combination of these implementation methods. The embodiments of this application can be implemented as a computer program or program code executed on a programmable system, which includes at least one processor, a storage system (including volatile and non-volatile memory and / or storage elements), at least one input device, and at least one output device.

[0164] Program code can be applied to input instructions to perform the functions described herein and generate output information. The output information can be applied to one or more output devices in a known manner. For the purposes of this application, a processing system includes any system having a processor such as, for example, a digital signal processor (DSP), a microcontroller, an application specific integrated circuit (ASIC), or a microprocessor.

[0165] Program code can be implemented with a high-level programming language or an object-oriented programming language to communicate with the processing system. Where necessary, program code can also be implemented in assembly language or machine language. In fact, the mechanism described in this application is not limited to the scope of any particular programming language. In either case, the language can be a compiled language or an interpreted language.

[0166] The fine-grained state response system, method, and application between React components based on Proxy and dependency injection disclosed in this embodiment can be used in the following scenarios:

[0167] Scenario 1: Large-scale, highly concurrent shopping cart components in e-commerce scenarios.

[0168] In e-commerce scenarios, a large number of users add and remove items from their shopping carts, and user interactions are frequent. If the native React table component is used to construct the shopping cart component, the system will generate a client-side Table component for each user. These numerous client-side Table components each maintain their own products, which can cause product or data loss during network fluctuations. This solution uses the dependency mapping principle to construct the shopping cart component. The corresponding relationship between users and products can be uniformly registered in the server-side dependency mapping table through the dependency tracking algorithm (Algorithm 1: Dependency Tracking). This centrally manages the relationship between all users and shopping carts, not only ensuring data integrity but also significantly resolving concurrency issues.

[0169] Scenario 2: Mutual exclusion of inventory in e-commerce scenarios.

[0170] In e-commerce scenarios, product inventories are mutually exclusive. If there are 100 items and a user adds one to their cart, 99 items remain. A shopping cart built with the native React Table component requires manual maintenance of dependency arrays such as user and item quantities through hook functions like useEffect. When useEffect detects a change in the item quantity, the inventory is manually maintained through communication between native React components. This solution uses the dependency mapping principle to construct a shopping cart component. When the item quantity in the shopping cart component changes, the triggerUpdate function is automatically called to modify the item inventory through the Change Notification algorithm (Algorithm 2: ChangeNotification).

[0171] Scenario 3: Real-time modification of products in e-commerce scenarios.

[0172] When a large number of users have added an item to their shopping carts and need to modify the price or quantity of an item, the communication principle between native React components makes it difficult to synchronize the modified product attributes to the shopping carts of these users in real time. However, by using the dependency mapping principle of this solution, when a product attribute is modified, the triggerUpdate function is automatically called through the Change Notification algorithm (Algorithm 2: Change Notification) to modify the corresponding attribute of the item in all users' shopping carts in real time.

[0173] Scenario 4: Modification of large data (large objects).

[0174] When a product has a large number of attributes, perhaps 100, and you need to modify a single attribute, the native React component state change principle requires modifying the product's object attributes, completely overwriting all 100 attribute values, which can result in significant performance degradation. This solution's dependency mapping principle allows for precise and detailed modifications to a single attribute without having to modify all 100 attribute values, significantly improving system performance.

[0175] As described above, although the present invention has been shown and described with reference to specific preferred embodiments, it should not be construed as limiting the present invention itself. Various changes may be made to it in form and detail without departing from the spirit and scope of the present invention as defined in the appended claims.

Claims

1. A fine-grained state response system between React components based on Proxy and dependency injection, characterized by: include: A centralized observable state storage module is used to store globally shared state, deeply proxy state objects through Proxy, intercept attribute read and write operations, and maintain a dependency mapping table to record the mapping relationship between state paths and subscribed component instances. The centralized observable state storage module includes a deep proxy function that recursively proxy each attribute of the state object to generate a Proxy instance containing the complete path. The dependency automatic tracking and registration module is integrated into the Proxy's get interceptor. When the component is rendered, it reads the state attribute, automatically captures the access, and registers the component instance and the exact path of the accessed attribute into the dependency map. The module for precise notification of state changes and triggering target updates is integrated into the set interceptor of the Proxy. When a state property is modified, it captures the write operation and searches for component instances that depend on the path according to the dependency mapping table, triggering their updates. The component dependency injection and connection module establishes a connection between the component and the state storage and declares the dependency intention through the hook function, registers the dependency when the component is mounted, and cleans up the subscription records in the dependency mapping table when it is uninstalled.

2. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1 is characterized in that: The centralized observable state storage module also includes: The dependency map uses a dot-separated string path as a key and stores a collection of component instances that subscribe to the path.

3. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 2 is characterized in that: The implementation of the depth proxy function includes: When reading the attribute value as an object, recursively call the deep proxy function and pass in the current path array to generate a nested Proxy; In the get interceptor, register the current rendering component instance and access path to the dependency mapping table.

4. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1 is characterized in that: The implementation of the dependency automatic tracking and registration module includes: In the get interceptor, concatenate the currently accessed attribute name into a full path array and convert it into a dot-separated path key; If there is a currently rendered component, call the dependency tracking algorithm to register the component instance and path key to the dependency map.

5. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1 is characterized in that: The implementation of the state change accurate notification and target update trigger module includes: In the set interceptor, compare the old and new property values ​​and trigger notification only when the value changes; Find the dependent component set copy according to the modification path, and call the forceUpdate method of the component to force it to re-render.

6. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1 is characterized in that: The component dependency injection and connection module includes: The useReactiveState hook function is used to generate a unique component ID, establish a connection with the state store, and set the global current rendering component context when the component is rendered; The dependency cleanup algorithm traverses the dependency mapping table when the component is uninstalled and removes all subscription records of the component.

7. A method for fine-grained state response between React components based on Proxy and dependency injection, implemented based on the fine-grained state response system between React components based on Proxy and dependency injection according to any one of claims 1 to 6, characterized in that: The steps include: Step 1: Create the state object of the deep proxy through the centralized observable state storage module and maintain the dependency mapping table; Step 2: When the component is rendered, the component instance and the accessed state path are registered in the dependency mapping table through the dependency automatic tracking and registration module; Step 3: When the state attribute is modified, the state change precise notification and target update trigger module trigger the update of related components according to the dependency mapping table; Step 4: Implement the connection between components and state storage and dependency declaration through component dependency injection and connection modules, and clean up dependency records during uninstallation.

8. The fine-grained state response method between React components based on Proxy and dependency injection according to claim 7 is characterized in that: Step 1 further includes: defining initial state data, recursively generating Proxy instances through the deep proxy function, and generating a path key containing a complete path when each attribute is accessed; Step 2 further includes: in the get interceptor of the Proxy, capturing the component's access to the state attribute, and registering the current rendering component instance and the path key in the dependency map; Step 3 further includes: in the set interceptor of the Proxy, comparing the old and new attribute values, searching for the dependent component based on the path key only when the value has changed, and calling the forceUpdate method of the component; Step 4 further includes: generating a component unique ID through the useReactiveState hook function, setting the current rendering component context when the component is mounted, and clearing subscription records in the dependency mapping table when the component is uninstalled.

9. The application of the fine-grained state response system between React components based on Proxy and dependency injection according to any one of claims 1 to 6, characterized in that: This includes any of the following applications: Application of shopping cart components in e-commerce scenarios; Application of inventory mutual exclusion in e-commerce scenarios; Application of real-time modification of products in e-commerce scenarios.

10. A computer-readable storage medium, characterized in that The storage medium stores at least one executable instruction, and when the executable instruction is executed on the electronic device, the electronic device executes the fine-grained state response method between React components based on Proxy and dependency injection as claimed in claim 7 or 8.

Citation Information

Patent Citations

  • Component processing method and device

    CN114297549A

  • Front-end component implementation method, device and system, electronic equipment and storage medium

    CN117873469A