Fine-grained state response system and method between React components based on Proxy and dependency injection and application of fine-grained state response system and method
Through the state response system between React components based on Proxy and dependency injection, the problems of coarse update granularity, large performance overhead and complex dependency management of state communication and dynamic rendering between React components are solved, and automatic dependency management and precise update of components are realized, improving system performance and development efficiency.
Patent Information
- Application Number
- CN202510919050.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-07-04
- Publication Date
- 2025-08-01
- Estimated Expiration
- 2045-07-04
AI Technical Summary
State communication and dynamic rendering among existing React components have problems such as coarse update granularity, large performance overhead, and complex dependency management. Especially when the component structure is complex and the dependencies are diverse, it is difficult to automatically and accurately track the specific dependence of the component on the state and update only the truly affected components.
The fine-grained state response system between React components based on Proxy and dependency injection is adopted. Automatic dependency management and precise update between components is realized through centralized observable state storage modules, dependency automatic tracking and registration modules, accurate notification of status changes and target update trigger modules, and component dependency injection and connection modules.
It realizes extremely fine-grained updates of components, reduces unnecessary DOM operations, improves system performance, simplifies component logic, improves development experience, and simplifies dependency management, avoiding errors caused by improper dependency management.
Smart Images

Figure CN120407051A_ABST
Abstract
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: 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.
[0004] 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.
[0005] 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.
[0006] 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.
[0007] 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
[0008] 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.
[0009] 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: 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. 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.
[0010] Optionally, the centralized observable state storage module includes: Deep proxy function, used to recursively proxy each property of the state object and generate a Proxy instance containing the complete path; The dependency map uses a dot-separated string path as a key and stores a collection of component instances that subscribe to the path.
[0011] Optionally, 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 rendered component instance and the access path into the dependency mapping table.
[0012] Optionally, the implementation of the dependency automatic tracking and registration module includes: In the get interceptor, splice the currently accessed property name into a complete 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 the path key into the dependency mapping table.
[0013] Optionally, the implementation of the state change precise notification and target update trigger module includes: In the set interceptor, compare the old and new property values and trigger a notification only when the value changes. Find a copy of the set of dependent components according to the modified path and call the forceUpdate method of the component to force it to re-render.
[0014] Optionally, the component dependency injection and connection module includes: The useReactiveState hook function is used to generate a unique ID for the component, establish a connection with the state store, and set the global current rendered component context when the component is rendered. The dependency cleaning algorithm traverses the dependency mapping table when the component is unmounted and removes all subscription records of the component.
[0015] In the second aspect of the present invention, a fine-grained state response method between React components based on Proxy and dependency injection is disclosed. This method depends on the system disclosed in the above first aspect to implement, and includes the following steps: Step 1, create a deeply proxied state object through the centralized observable state storage module and maintain the dependency mapping table. Step 2, when the component is rendered, register the component instance and the accessed state path into the dependency mapping table through the dependency automatic tracking and registration module. Step 3, when the state property is modified, trigger the update of relevant components according to the dependency mapping table through the state change precise notification and target update trigger module. Step 4, implement the connection between the component and the state store and the dependency declaration through the component dependency injection and connection module, and clean up the dependency records when unmounted.
[0016] Optionally, step 1 further includes: define the initial state data, recursively generate Proxy instances through the deep proxy function, and generate path keys containing the complete path when each property is accessed.
[0017] Optionally, step 2 further includes: in the get interceptor of the Proxy, capturing the access of the component to the state property, and registering the current rendered component instance and the path key into the dependency mapping table.
[0018] Optionally, step 3 further includes: in the set interceptor of the Proxy, comparing the old and new property values, and only when the value changes, looking up the dependent components according to the path key and calling the forceUpdate method of the component.
[0019] Optionally, step 4 further includes: generating a unique ID for the component through the useReactiveState hook function, setting the current rendered component context when the component is mounted, and cleaning up the subscription records in the dependency mapping table when the component is unmounted.
[0020] In the third aspect of the present invention, the application of the above-mentioned fine-grained state response system between React components based on Proxy and dependency injection is disclosed, including any one of the following applications: Application in the shopping cart component in the e-commerce scenario; Application of inventory mutual exclusion in the e-commerce scenario; Application of real-time modification of goods in the e-commerce scenario.
[0021] In the fourth aspect of the present invention, a computer-readable storage medium is disclosed. At least one executable instruction is stored in the storage medium. When the executable instruction runs on an electronic device, the electronic device is caused to execute the fine-grained state response method between React components based on Proxy and dependency injection disclosed in the second aspect.
[0022] Compared with the prior art, the technical solution of the present invention has the following beneficial technical effects: (1) Ultra-fine-grained update: Based on the automatic dependency tracking of Proxy, it can be accurate to the specific property path level of the state object. Only when the smallest state unit actually depended on by the component changes, the component will be re-rendered, minimizing unnecessary DOM operations and significantly improving the performance of the system, especially in scenarios where the state object is large, has a complex structure, or is updated frequently.
[0023] (2) Automatic dependency management: Developers do not need to manually maintain the dependency array of useEffect. The dependency relationship is automatically established and updated when the component renders and accesses the state, reducing errors caused by improper dependency management, such as state out-of-sync due to missing dependencies or performance degradation due to including irrelevant dependencies.
[0024] (3) Simplify component logic: Encapsulate the complex logic of state subscription and update triggering inside the system. The component only needs to declare the dependency intention and directly read and write the state, making the component code more concise and more focused on the business logic.
[0025] (4) Improve the development experience: The automation and precision features make state management more intuitive and easier to debug.
[0026] (5) Easy to integrate: It can be introduced as a plugin or library for existing React applications, providing good type support when combined with TypeScript. Brief Description of the Drawings
[0027] Figure 1 It is a fine-grained state response flowchart between React components based on Proxy and dependency injection in the embodiment. Specific Embodiments
[0028] In the following description, a large number of specific details are given to provide a more thorough understanding of the present invention. However, it is obvious to those skilled in the art that the present invention can be implemented without one or more of these details. In other examples, some technical features well known to the art are not described to avoid confusion with the present invention.
[0029] 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. The present invention systematically combines the automatic fine-grained dependency tracking ability of deep Proxy with the connection mechanism of React components, such as using HOC, Hook, etc., to form a complete, automated, and property-path-precise reactive update method and system architecture. This system is applied to front-end applications based on React and TypeScript, and the specific construction process is as follows: Step S1: Define a centralized observable state storage module, Centralized Observable StateStore Module. It is responsible for storing the global shared state of components. The core state object of the component is deeply proxied through the Proxy of this module, and the read and write operations of the state object properties are intercepted through the Proxy. A dependency map, Dependency Map, is maintained inside this module, recording the mapping relationship between the path of each specific property of the state object, such as user, user.name, user.email, and the component instances that have subscribed to this path.
[0030] Step S2: Define the Dependency Auto-Tracking and Registration Module, Dependency Auto-Tracking and Registration Module, which is integrated into the get interception of the Proxy. When a component with an injected dependency first reads a property of the state object proxied by the Proxy during the rendering process, this module automatically captures this access and registers the current component instance and the exact path of the accessed property into the above-mentioned dependency mapping table, without the need to manually maintain a dependency array like useEffect, such as: useEffect(() => {...}, [page, pageSize, sort, sortOrder, formQuery]);.
[0031] Step S3: Define the Precise State Change Notification and Targeted Update Trigger Module, Precise State Change Notification and Targeted Update Trigger Module, which is integrated into the set interception of the Proxy. When a property of the state object is modified, this module captures this write operation. Then, based on the path of the modified property, it looks up all component instances registered in the dependency mapping table that have a dependency on this path or its parent path, and then sends an update signal only to these precisely identified component instances.
[0032] Step S4: Define the Component Dependency Injection and Connection Module, Component Dependency Injection and Connection Module. This module is responsible for establishing a connection with the state store and declaring the dependency intention through the useReactiveState hook function when the component is mounted, such as whether it needs to access user, user.name, or user.email. It automatically clears all subscription records in the dependency mapping table when the component is unmounted. This module is also responsible for providing interfaces for the component to access and modify the data in the state store.
[0033] As a preferred embodiment, the following specific steps can be taken to implement Step S1.
[0034] Step S1.1: Create a centralized observable state store module.
[0035] Define the initial state data of the application, initialState. The initial state data contains the user object and the cart object, such as: initialState{user:{id:1,name:'张三',email:'zhangsan@example.com'},cart:{items:[{productId:'prod001',productName:'笔记',quantity:1,price:688},{…}]},total:799}.
[0036] Step S1.2: Define the type of the component instance, which can be a unique identifier of a class component or a function component, as follows: type ComponentInstance = React.Component | { _id: number; _update: (val: number) => void}; Step S1.3: Define the type of the state path as a string using the following method: type StatePath = string; Step S1.4: Define a variable currentRenderingComponent to track the component instance currently being rendered, CRC-Current Rendering Component. The method is: letcurrentRenderingComponent: ComponentInstance | null = null; Step S1.5: Create an observable state storage instance createObservableStore, with the input parameter being the initial state data initialState, and returning a mutations object containing the proxied state and methods for modifying the state. The method is: function createObservableStore<T extends object> (initialState: T){…} 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 {…} Step S1.7: Use the deep proxy function deepProxy 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, defaulting to an empty array. The method is: const state = deepProxy(initialState,[]); Step S1.8: Create a new React Native Proxy in the deep proxy function deepProxy to create a new Proxy instance for the current object. The method is: return new Proxy(obj, {...})
[0037] Step S1.9: Create a get interceptor and record the dependency of the current rendering component on the current path key.
[0038] A. Create a get interceptor for the obj object in the Proxy, which is triggered when reading object properties. The method is: get(target,prop,receiver){...}
[0039] B. Define an array of path variables currentPathArray, and add the currently accessed property name (prop) to the path array currentPathArray to form a complete path array for the current property, such as: [user], [user,name], [user,email]. The method is: const currentPathArray = path.concat(String(prop)); 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, user.email. The method is: const pathKey =currentPathArray.join('.')
[0040] D. If there is a currently rendering component, 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 currently rendered component currentRenderingComponent and the path key pathKey. The method is: if (currentRenderingComponent) { trackDependency(currentRenderingComponent,pathKey )}; E. Define a variable `value` to store the original property value of the obtained target object. The method is `const value = Reflect.get(target, prop, receiver)`.
[0041] F. If the property value of `value` is an object and not empty, take `currentPathArray` as a parameter, recursively create and return a new `Proxy` for this property value object 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 property in the object. The method is: `if (typeof value === 'object') {return deepProxy(value,currentPathArray)};` G. Finally, return the proxied object. The method is: `return value;` 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 be updated.
[0042] A. Write a `set` interceptor for the `obj` object in the `Proxy`, which is triggered when modifying the object property. The method is: `set(target, prop, value, receiver){…}`.
[0043] B. Define an array of path variables `currentPathArray`, and add the currently accessed property name (`prop`) to the path array `currentPathArray` to form a complete path array for the current property, such as `[user]`, `[user,name]`, `[user,email]`. The method is: `const currentPathArray = path.concat(String(prop));` 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`, `user.email`. The method is: `const pathKey =currentPathArray.join('.')`.
[0044] 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);` E. Compare the object property value `previousValue` before the modification with the new value to be modified. If the new value is the same as the old value (using `Object.is` for strict comparison), do not perform any operation and directly return `true` to indicate that the modification is successful (but there is no actual change). The method is: `if (Object.is(previousValue, value)) return true;` F. Define a variable `result` to store the object property value after the modification. If the new value is different from the old value, use `Reflect.set` to modify the property value of the target object and put it into `result`, and at the same time obtain the result of whether the operation is successful. The method is: `const result = Reflect.set(target,prop,value,receiver);` G. If the modification operation is successful, call the change notification algorithm `notifyChange` in the "Precise State Change Notification and Target Update Trigger Module" to notify all components that depend on this path key to be updated. The method is as follows: `if (result){notifyChange(pathKey)};` H. Finally, return the proxied object (the result of the modification operation). The method is: `return result;` Step S1.11: Create predefined methods `Mutations` for modifying the state in the state storage instance `createObservableStore`. These methods allow external callers to directly operate on the proxied `state` object, thereby automatically triggering the `set` interceptor of the `Proxy`. The method is: `const mutations = {...};` A. Create a method for modifying user properties in the `Mutations` method. The method is: `updateUserName(newName: string): void { (state as AppState).user.name = newName}` B. Create a method to add an item to the shopping cart in the Mutations method. The method is: addItemToCart(item: { productId: string; productName: string; quantity: number}): void {…} Step S1.12: Return an object that contains the proxied state object (state) and the method to modify the state (mutations). The method is: return { state: state as T, mutations}
[0045] As a preferred embodiment, the following specific steps can be taken to implement Step S2.
[0046] Step S2.1: Create a module for automatic dependency tracking and registration Create a dependency tracking algorithm, Algorithm 1: Dependency Tracking. The method is: function trackDependency(componentInstance: ComponentInstance, path: StatePath): void{…}. The input parameters are componentInstance, the currently rendered component instance, and path, the state path.
[0047] 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 have been passed as parameters to the dependency tracking algorithm trackDependency. After the parameter name conversion in the dependency tracking algorithm, the name of the currently rendered component instance inside the method is ComponentInstance, and the component path name is path.
[0048] Step S2.3: Automatic dependency. Define a set dependents to store the set of dependent components that already exist for the current path (path) obtained from the dependency map. The method is: let dependents = dependencyMap.get(path); Step S2.4: Check if there are any dependencies. If there are no components depending on this path yet, create a new Set to store the components that depend on this path. The method is: if (!dependents) { dependents = new Set()}
[0049] Step S2.5: First, register the path. Method: dependencyMap.set(path, dependents); Step S2.6: Then, register the component. Determine if the current component instance has not been recorded as a dependent of this path. If not, add the current component instance to the dependent set of this path. Method: if (!dependents.has(componentInstance)) { dependents.add(componentInstance)}
[0050] As a preferred embodiment, the following specific steps can be taken to implement Step S3.
[0051] Step S3.1: State change precise notification and target update trigger module Create a change notification algorithm, Algorithm 2: Change Notification. Method: function notifyChange(path: StatePath): void {...}, where the input parameter StatePath is the state path that has been modified.
[0052] Step S3.2: State change precise notification. In the set interception of the "observable state storage module" in Step S1.10, the path key pathKey of the currently modified component instance has been passed as a parameter to the change notification algorithm trackDependency. After the parameter name conversion of the change notification algorithm, the path name of the currently modified component instance inside the method is path.
[0053] Step S3.3: Define a set dependents to store the set of components that depend on this path obtained from the dependency map. Method: const dependents = dependencyMap.get(path); Step S3.4: Determine if there are dependencies. If there are dependencies, create a copy of the dependent component set to prevent the set from being modified due to component unloading or other reasons during subsequent traversal. Method: if(dependents && dependents.size>0) { const notifySet = new Set(dependents)}; Step S3.5: Target update trigger. Traverse the copy notifySet of the dependent component set, traverse each dependent component instance in the copy notifySet, and call the triggerUpdate function one by one to notify the component to perform an update. The method is: notifySet.forEach((componentInstance) => { triggerUpdate(componentInstance)}); Step S3.6: Dependent target update.
[0054] A. Create a function triggerUpdate for triggering component updates. The input parameter is the component instance componentInstance to be updated. The method is: function triggerUpdate(componentInstance:ComponentInstance): void {…}; B. Check whether the component instance componentInstance is a React class component and whether there is a forceUpdate method on its instance. The method is: if ( componentInstance instanceof React.Component && typeof componentInstance.forceUpdate === 'function') {…} C. Trigger the update of the component. Call the forceUpdate method of the class component to force it to re-render. The method is: componentInstance.forceUpdate().
[0055] As a preferred embodiment, the following specific steps can be taken to implement Step S4.
[0056] Step S4.1: Create a component dependency injection and connection module Export the global observable storage instance store for the component connection module to connect to store. The parameter is the initial state data initialState of the application. The method is: export const store = createObservableStore(initialState); Step S4.2: Create a connection module method function useReactiveState for connecting a 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() {…}; Step S4.3: Create a component update mechanism. Use useState to create a state and its update function. By obtaining the forceUpdate function, it is used to force the component to re-render when needed. The method is: const [, forceUpdate] = useState(0); Step S4.4: Assign a unique component identifier. Use useMemo to generate an ID that remains unique throughout the component's lifecycle. By incrementing nextComponentId++, it ensures that each call to the Hook (i.e., each component instance) has a different ID. The method is: const componentId = useMemo(() => nextComponentId++, []); Step S4.5: Create a stable component reference. Use useRef to create a stable reference (componentRef) that remains unchanged during multiple renders of the component. This reference object contains the component's unique ID (_id) and its update function (_update). Through the.current property, even if the component re-renders, the same object is still accessed. The method is: const componentRef = useRef({ _id: componentId, _update: forceUpdate}).current; Step S4.6: Set the rendering context. Before the component starts rendering, save the reference (previousCRC) of the previous component that was being rendered. The method is: const previousCRC = currentRenderingComponent. Set the component instance where the current Hook is located, i.e., componentRef, as the global currentRenderingComponent. In this way, during the rendering of the current component, any access to the proxy state will register this componentRef as a dependent. The method is: currentRenderingComponent = componentRef; 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. The method is: if (currentRenderingComponent === componentRef) { currentRenderingComponent = previousCRC}; Example: Component A starts to render, and set currentRenderingComponent = A; during the rendering process of Component A, it renders sub-component B; when Component B starts to render, it needs to save previousCRC = A first; then set currentRenderingComponent = B; after B finishes rendering, it needs to restore currentRenderingComponent = previousCRC (i.e., A).
[0057] 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}; Step S4.9: Component connection. There is an existing UserProfile file, and 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, it can be connected to the global storage instance store through the useReactiveState function, and the current state of the component and the method for modifying the state can be accessed 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 item for the user.name path, realizing automatic injection of dependencies.
[0058] Step S4.11: Provide an interface component. Create a handleUpdateName function in the UserProfile function 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 on the mutations object in the store instance. This triggers the proxy's set interceptor, automatically running the change notification algorithm for the user.name path, causing the UserProfile component to re-render.
[0059] Step S4.12: Clean up the dependency mapping table when the component is uninstalled.
[0060] A. Create a dependency cleanup algorithm (Algorithm 3: Dependency Cleanup) with the following method: function cleanupDependencies(componentInstance: ComponentInstance): void {…}, where the input parameter is the component instance componentInstance to be uninstalled.
[0061] B. Iterate over each entry in the dependency map, including the path and the set of components that depend on that path, using the following method: dependencyMap.forEach((dependents,path) =>{…}; C. If the current component instance exists in the dependent component set of the path, remove the current component instance from the dependent component set of the path by: if (dependents.has(componentInstance)) {dependents.delete(componentInstance )}; D. In the useReactiveState method of the connection module, hook the componentRef with 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]).
[0062] The following shows a fine-grained state response example between components of user and cart through Proxy and dependency injection during complex operations.
[0063] 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}}; There is existing initial state data initialState, which contains a user object user and a cart object cart, and the two objects have been initialized and assigned values. Now, connect the two React files UserProfile.tsx and ShoppingCart.tsx to the "centralized observable state storage module" through the "dependency injection and connection module", and use deep proxy through Proxy when operating on the user object and the cart object to achieve fine-grained state response between components. During the implementation of the embodiment, it is possible to observe the fine-grained state response between components, the automatic injection process of dependency paths and component instances in the dependency mapping table, and the precise notification and targeted update of state changes after the components change. The principle of the present invention can be further understood through the example.
[0064] Step 1: Component connection and dependency declaration.
[0065] Step 1.1: Import the useReactiveState function in the "component dependency injection and connection module" respectively in the two files UserProfile.tsx and ShoppingCart.tsx, import { useReactiveState} from '. / observableStore'.
[0066] 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.
[0067] 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.
[0068] Define the handleUpdateName method in the UserProfile function to modify the user name.
[0069] const handleUpdateName = () =>{ const newName = `Li Si (renamed to ${new Date())}`; mutations.updateUserName(newName);}; 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.
[0070] 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.
[0071] const handleAddItem = () => { const newItemId = `prod${Date.now().toString()}${Math.floor(Math.random()*100)}`; const newItemName = `New Item) ${Math.floor(Math.random() *1000)}`; const newItemPrice = Math.floor(Math.random() * 200) + 50;} Step 2: Component rendering and dependency tracking Step 2.1: Component rendering.
[0072] 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.
[0073] Step 2.2: Component tracing.
[0074] 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.
[0075] 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.
[0076] Table 1: DependencyMap dependency mapping table
[0077] Step 3: State Change, Change Capture, and Accurate Notification 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); 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.
[0078] 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,}); At this time, the modification of cart.item is captured by the set trap of the Proxy. Through the change notification algorithm, the ShoppingCart (id: 1) component that depends on cart.item is found in the dependency mapping table, and the triggerUpdate function is called to notify the ShoppingCart (id: 1) component to perform an update.
[0079] Step 4: Targeted update The system only sends update signals to the components found in Step 4, triggering the re-rendering of these components. For example, other components that do not depend on user.name, even if they are also connected to the state store or depend on other parts of the state, such as store.state.cart.items, will not be triggered to update.
[0080] Step 5: Component unloading and cleanup The global state store hooks the componentRef of the caller through the useEffect hook function, and automatically calls 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]).
[0081] The 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 each function or step executed in the above method embodiment, which will not be elaborated here.
[0082] The embodiment of the present application also provides a computer-readable storage medium, which includes computer instructions. When the computer instructions run on the above electronic device, the electronic device is enabled to execute each function or step executed in the above method embodiment, which will not be elaborated here.
[0083] The embodiment of the present application also provides a computer program product. When the computer program product runs on a computer, the computer is enabled to execute each function or step executed in the above method embodiment, which will not be elaborated here.
[0084] Each embodiment of the mechanism disclosed in the present application can be implemented in hardware, software, firmware, or a combination of these implementation methods. The embodiments of the present 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 memories and / or storage elements), at least one input device, and at least one output device.
[0085] The program code can be applied to the input instructions to perform the various functions described in this application 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.
[0086] The program code can be implemented in a high-level procedural language or an object-oriented programming language to communicate with the processing system. When needed, the program code can also be implemented in assembly language or machine language. In fact, the mechanisms described in this application are not limited to the scope of any specific programming language. In either case, the language can be a compiled language or an interpreted language.
[0087] The fine-grained state response system, method, and its application between React components based on Proxy and dependency injection disclosed in this embodiment can be used in the following scenarios: Scenario 1: Large-scale and high-concurrency shopping cart components in the e-commerce scenario.
[0088] In the e-commerce scenario, a large number of users add or remove items from the shopping cart, and user interaction behaviors are frequent. If the native React table component Table is used to construct the shopping cart component, the system will generate a client-side Table component for each user, and a large number of client-side Table components will each maintain their own items. In case of network fluctuations, it will cause the loss of items or data. By constructing the shopping cart component through the principle of the dependency mapping table in this solution, the correspondence between users and items can be uniformly registered in the dependency mapping table on the server side through the dependency tracking algorithm (Algorithm 1: Dependency Tracking), and the relationships between all users and shopping carts can be centrally managed. This not only achieves data integrity but also greatly solves the concurrency problem.
[0089] Scenario 2: Mutual exclusion of inventory in the e-commerce scenario.
[0090] In the e-commerce scenario, the inventory of goods is mutually exclusive. For example, if there are 100 items, and a user adds 1 item to the shopping cart, then there are 99 items left. For a shopping cart built with the React Native Table component, it is necessary to manually maintain dependency arrays such as users and item quantities through hook functions like useEffect. When useEffect detects a change in the item quantity, the inventory quantity needs to be manually maintained through communication between native React components. By constructing the shopping cart component based on the dependency mapping table principle of this solution, when the quantity of an item in the shopping cart component changes, the triggerUpdate function will be automatically called through the change notification algorithm (Algorithm 2: ChangeNotification) to modify the item inventory.
[0091] Scenario 3: Real-time modification of items in the e-commerce scenario.
[0092] When a large number of users have added a certain item to the shopping cart and it is necessary to modify the price or quantity of the item, it is very difficult to achieve real-time synchronization of the modified item attributes to the shopping carts of a large number of users through the communication principle between native React components. Through the dependency mapping table principle of this solution, when a certain attribute of an item is modified, the triggerUpdate function will be automatically called through the change notification algorithm (Algorithm 2: Change Notification) to modify the corresponding attributes of this item in all users' shopping carts in real time.
[0093] Scenario 4: Modification of big data (large objects).
[0094] When an item has a large number of attributes, for example, 100 attributes, and it is necessary to modify a certain attribute of this item, the principle of changing the state of a native React component needs to be modified at the object attribute level (object) of the item, that is, completely overwrite the 100 attribute values of this item, which will cause extremely high performance consumption. Through the dependency mapping table principle of this solution, a certain attribute of the item can be precisely modified with a fine granularity, without the need to modify all 100 attribute values of the item, greatly improving the performance of the system.
[0095] As described above, although the present invention has been shown and described with reference to specific preferred embodiments, it should not be construed as a limitation of the present invention itself. Various changes may be made in its form and details without departing from the spirit and scope of the present invention defined by the appended claims.
Claims
1. A fine-grained state response system between React components based on Proxy and dependency injection, characterized in that including: A centralized observable state storage module for storing global shared states, deeply proxying state objects through a Proxy and intercepting property read and write operations, and maintaining a dependency mapping table to record the mapping relationship between state paths and subscribed component instances; A dependency automatic tracking and registration module integrated into the get interceptor of the Proxy. When a component is rendered, it reads state properties, automatically captures the access, and registers the component instance and the exact path of the accessed property into the dependency mapping table; A state change precise notification and target update trigger module integrated into the set interceptor of the Proxy. When a state property is modified, it captures the write operation, looks up the component instances depending on this path according to the dependency mapping table, and triggers their updates; A component dependency injection and connection module that establishes a connection between the component and the state storage through a hook function and declares the dependency intention, registers the dependency when the component is mounted, and clears the subscription records in the dependency mapping table when the component is unmounted.
2. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1, wherein The centralized observable state storage module includes: A deep proxy function for recursively proxying each property of the state object to generate a Proxy instance containing the full path; A dependency mapping table with a dot-separated string path as the key, storing the set of component instances subscribing to this path.
3. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 2, wherein The implementation of the deep proxy function includes: When the property value read is 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 the access path into the dependency mapping table.
4. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1, wherein The implementation of the dependency automatic tracking and registration module includes: In the get interceptor, concatenate the currently accessed property name into a full path array and convert it into a dot-separated path key; If the current rendering component exists, call the dependency tracking algorithm to register the component instance and the path key into the dependency mapping table.
5. The fine-grained state response system between React components based on Proxy and dependency injection according to claim 1, wherein The implementation of the state change precise notification and target update trigger module includes: In the set interceptor, compare the old and new property values and trigger a notification only when the value changes; Find a copy of the set of dependent components according to the modified 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, characterized in that, The component dependency injection and connection module includes: The useReactiveState hook function for generating a unique ID for the component, establishing a connection with the state storage, and setting the global current rendering component context when the component is rendered; A dependency cleaning algorithm that traverses the dependency mapping table when the component is unmounted and removes all subscription records of this component.
7. A fine-grained state response method 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, including the following steps: Step 1, create a deeply proxied state object through the centralized observable state storage module and maintain a dependency mapping table; Step 2, when the component is rendered, register the component instance and the accessed state path into the dependency mapping table through the dependency automatic tracking and registration module; Step 3, when the state property is modified, trigger the update of relevant components according to the dependency mapping table through the state change precise notification and target update trigger module; Step 4, implement the connection between the component and the state storage and the dependency declaration through the component dependency injection and connection module, and clear the dependency records when the component is unmounted.
8. The fine-grained state response method between React components based on Proxy and dependency injection according to claim 7, characterized in that, Step 1 further includes: defining initial state data, recursively generating Proxy instances through a deep proxy function, and generating a path key containing the full path when each property is accessed; Step 2 further includes: in the get interceptor of the Proxy, capturing the access of the component to the state property, and registering the current rendered component instance and the path key to the dependency mapping table; Step 3 further includes: in the set interceptor of the Proxy, comparing the old and new property values, and only when the value changes, looking up the dependent components according to the path key and calling the forceUpdate method of the component; Step 4 further includes: generating a unique ID for the component through the useReactiveState hook function, setting the current rendered component context when the component is mounted, and cleaning up the subscription records in the dependency mapping table when the component is unmounted.
9. 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 Including any one of the following applications: Application of the shopping cart component in the e-commerce scenario; Application of inventory mutual exclusion in the e-commerce scenario; Application of real-time modification of goods in the e-commerce scenario.
10. A computer-readable storage medium, characterized in that, At least one executable instruction is stored in the storage medium, and when the executable instruction runs on an electronic device, the electronic device is caused to execute the fine-grained state response method between React components based on Proxy and dependency injection as described 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
Method for realizing component dynamic import execution in react framework
CN119847536A
Exploit prevention and malicious code neutralization method and system for javascript-enabled applications
WO2022044020A1
Cited By
Side effect recovery method and device, equipment and storage medium
CN121636374A
React component state penetrating and broadcasting method and system based on binary bit mask and application
CN121807406A
A binary bit-mask-based react component state penetration and broadcast method, system and application
CN121807406B