RFC: [Feature Request] Inject structural change metadata (`ChangePayload`) as an argument into the `useEffect` callback
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- javascript, react
- Ambito
- frontend
Direzione di ricerca
L’issue non indica alcun file del repository, test o punto di ingresso. Inizia esaminando la firma proposta di useEffect e il design di ChangePayload, quindi determina se il lavoro riguarda react.dev o il React reconciler. Un punto di partenza utilizzabile richiederebbe un design concordato e l’identificazione delle posizioni per l’implementazione e i test.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
[Feature Request] Inject structural change metadata (ChangePayload) as an argument into the useEffect callback
Summary
I propose extending the signature of the useEffect callback function to optionally accept a single argument: a ChangePayload object. This metadata object provides explicit access to current values, previous values, and an array of indices representing exactly which dependencies triggered the current effect execution pass.
Motivation
In legacy class components, developers had granular, imperative control over side-effect execution branching via the componentDidUpdate(prevProps, prevState) lifecycle method. This allowed developers to easily evaluate the precise delta between frames (e.g., if (this.props.id !== prevProps.id)).
With functional components and useEffect, this diagnostic visibility was fully abstracted away. If an effect relies on multiple cohesive dependencies, the callback executes blindly without knowing the specific trigger vector.
The Analogy to useReducer:
Much like a reducer function receives a discrete action object with a type/payload to determine how state should mutate, a multi-dependency useEffect callback should be able to receive a change payload to determine how side-effect execution should branch. Currently, developers are forced to choose between splitting code across multiple disconnected effects (fragmenting logic) or managing complex useRef snapshots to diff properties manually.
Detailed Design
We propose modifying the execution lifecycle so that the reconciler injects a structured payload directly into the effect callback:
interface ChangePayload<T extends ReadonlyArray<unknown>> {
currentDepValues: T;
previousDepValues: T;
updatedDepIndex: number[]; // Array of dependency indices that failed equality checks
}
Code Implementation Example:
Instead of managing tracking refs, developers can treat dependency mutations as distinct event triggers within a single, cohesive side-effect block:
import { useEffect, useState } from 'react';
export function CoreDataEngine() {
const [authHeader, setAuthHeader] = useState('Bearer xyz');
const [streamPayload, setStreamPayload] = useState({ coordinates: [] });
const [circuitBreaker, setCircuitBreaker] = useState(false);
useEffect((changePayload) => {
// If changePayload is undefined, it is the initial mount pass
if (!changePayload) return;
const { updatedDepIndex, currentDepValues, previousDepValues } = changePayload;
// Direct branching reminiscent of action-handling in useReducer
if (updatedDepIndex.includes(0)) {
console.log(`Auth token updated from ${previousDepValues[0]} to ${currentDepValues[0]}. Re-signing sockets.`);
// execTokenRotation();
}
if (updatedDepIndex.includes(1)) {
console.log('Telemetry coordinate payload arrived. Re-rendering stream vectors.');
// execVectorRender();
}
if (updatedDepIndex.includes(2)) {
console.log('System critical circuit breaker tripped. Terminating pipelines.');
// execEmergencyTeardown();
}
}, [authHeader, streamPayload, circuitBreaker]); // Index 0, 1, 2
}
Key Advantages
- Unifies Contextual Logic: Eliminates the anti-pattern of splitting highly cohesive dependencies into 3 or 4 separate
useEffectdeclarations simply because their runtime execution logic differs slightly based on what changed. - Deterministic Control Over Batching: When React batches multiple state setters together,
updatedDepIndexprovides an array of all indices that mutated in that specific batch, giving developers a clear execution map of the transaction. - Ergonomic Parity with class lifecycles: Brings back the missing granular diffing power of
componentDidUpdatewithout introducing stateful lifecycle clutter to functional components.
Alternatives Considered
The primary alternative is user-land implementation via custom hooks wrapping useRef. However, this requires continuous overhead, duplicate shallow/deep equality evaluation outside the Fiber loop, and forces every enterprise engineering team to repeatedly implement custom snapshot logic to solve a standard primitive constraint.
- Lingua principale
- JavaScript
- Stelle
- 11.8k
- Fork
- 7.9k
- Merge medio
- 16h 6m
- PR unite (30g)
- 7
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di reactjs/react.dev
-
type: documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
-
bug: unconfirmed
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
-
type: typos
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
-
bug: unconfirmed
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
Tutte le issue di reactjs/react.dev
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
avniproject/avni-client#2135 ·
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
babalae/bettergi-scripts-list#3674 ·
-
A-Release-Notes C-Editing D-Modest S-Ready-For-Implementation
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
bevyengine/bevy-website#2595 ·
-
ecosystem wording
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
matrix-org/matrix.org#3649 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
vadimdemedes/ink#1029 ·