ਤੁਸੀਂ ਪੇਜ ਨੂੰ ਰਿਫ੍ਰੈਸ਼ ਕਰਦੇ ਹੋ ਅਤੇ ਸਕ੍ਰੀਨ ਖਾਲੀ ਰਹਿੰਦੀ ਹੈ। ਜਾਂ ਸ਼ਾਇਦ ਕਿਸੇ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰਨ ਨਾਲ ਤੁਹਾਡੇ CPU ਦਾ ਫੈਨ ਬਹੁਤ ਤੇਜ਼ ਚੱਲਣ ਲੱਗ ਜਾਂਦਾ ਹੈ। ਫਿਰ ਕੰਸੋਲ ਵਿੱਚ ਉਹ ਡਰਾਉਣੀ ਚੇਤਾਵਨੀ ਆਉਂਦੀ ਹੈ: Maximum update depth exceeded. React ਨੇ ਬ੍ਰੇਕ ਲਗਾ ਦਿੱਤੀ ਹੈ ਕਿਉਂਕਿ ਤੁਹਾਡਾ component ਇੱਕ ਅਨੰਤ ਲੂਪ (infinite loop) ਵਿੱਚ ਫਸ ਗਿਆ ਹੈ। ਇਹ React ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਿੱਚ ਸਭ ਤੋਂ ਆਮ ਗਲਤੀਆਂ ਵਿੱਚੋਂ ਇੱਕ ਹੈ, ਅਤੇ ਇਹ ਆਮ ਤੌਰ 'ਤੇ ਇਸ ਗੱਲ ਦੀ ਮਾਮੂਲੀ ਗਲਤਫਹਿਮੀ ਤੋਂ ਪੈਦਾ ਹੁੰਦੀ ਹੈ ਕਿ ਤੁਹਾਡਾ ਕੋਡ ਅਸਲ ਵਿੱਚ ਕਦੋਂ ਚੱਲਦਾ ਹੈ।
ਇਸ ਨੂੰ ਠੀਕ ਕਰਨ ਲਈ, ਤੁਹਾਨੂੰ ਉਸ ਸਹੀ ਪਲ ਨੂੰ ਸਮਝਣ ਦੀ ਲੋੜ ਹੈ ਜਦੋਂ ਇੱਕ render ਇੱਕ re-render ਬਣ ਜਾਂਦਾ ਹੈ, ਅਤੇ ਕਿਉਂ state ਦੇ ਬਦਲਾਅ render ਦੇ ਰਸਤੇ ਤੋਂ ਬਾਹਰ ਰਹਿਣੇ ਚਾਹੀਦੇ ਹਨ।
React ਤੁਹਾਡੇ Component ਨੂੰ ਕਿਵੇਂ Render ਕਰਦਾ ਹੈ
React components ਤੋਂ ਯੂਜ਼ਰ ਇੰਟਰਫੇਸ (user interfaces) ਬਣਾਉਂਦਾ ਹੈ। ਆਧੁਨਿਕ React ਵਿੱਚ, ਉਹ components ਫੰਕਸ਼ਨ (functions) ਹੁੰਦੇ ਹਨ। ਹਰ ਵਾਰ ਜਦੋਂ React ਨੂੰ ਸਕ੍ਰੀਨ 'ਤੇ ਤੁਹਾਡਾ component ਦਿਖਾਉਣ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ, ਤਾਂ ਇਹ ਸਿਰਫ਼ ਉਸ ਫੰਕਸ਼ਨ ਨੂੰ ਕਾਲ (call) ਕਰਦਾ ਹੈ। ਫੰਕਸ਼ਨ ਦੇ ਅੰਦਰ, ਤੁਸੀਂ renders ਦੇ ਵਿਚਕਾਰ ਚੀਜ਼ਾਂ ਨੂੰ ਯਾਦ ਰੱਖਣ ਲਈ state ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹੋ। State React ਨੂੰ ਦੱਸਦੀ ਹੈ ਕਿ ਕਿਹੜਾ ਡੇਟਾ component ਨਾਲ ਸਬੰਧਤ ਹੈ ਅਤੇ, ਸਭ ਤੋਂ ਮਹੱਤਵਪੂਰਨ ਗੱਲ ਇਹ ਕਿ, ਕਦੋਂ ਕੁਝ ਬਦਲ ਗਿਆ ਹੈ ਅਤੇ UI ਨੂੰ ਅਪਡੇਟ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।
ਜਦੋਂ state ਬਦਲਦੀ ਹੈ, ਤਾਂ React ਇੱਕ ਨਵਾਂ render ਸ਼ਡਿਊਲ ਕਰਦਾ ਹੈ। Component ਫੰਕਸ਼ਨ ਦੁਬਾਰਾ ਚੱਲਦਾ ਹੈ, ਨਵਾਂ JSX ਰਿਟਰਨ ਕਰਦਾ ਹੈ, ਅਤੇ React ਉਸ ਦੇ ਅਨੁਸਾਰ DOM ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ। ਆਮ ਵਰਤੋਂ ਵਿੱਚ, ਇਹ ਚੱਕਰ ਨੁਕਸਾਨਦੇਹ ਨਹੀਂ ਹੁੰਦਾ। ਤੁਸੀਂ ਇੱਕ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰਦੇ ਹੋ, ਇੱਕ event handler state ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ, React ਇੱਕ ਵਾਰ re-render ਹੁੰਦਾ ਹੈ, ਅਤੇ ਯੂਜ਼ਰ ਨੂੰ ਨਵਾਂ ਟੈਕਸਟ ਜਾਂ ਰੰਗ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ।
ਗਲਤੀ ਉਦੋਂ ਆਉਂਦੀ ਹੈ ਜਦੋਂ ਇੱਕ render ਆਪਣੇ ਆਪ ਵਿੱਚ ਹੀ ਦੂਜੀ state update ਨੂੰ ਟ੍ਰਿਗਰ (trigger) ਕਰ ਦਿੰਦਾ ਹੈ। ਉਹ ਨਵੀਂ state update ਇੱਕ ਹੋਰ render ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਦੀ ਹੈ, ਜੋ ਇੱਕ ਹੋਰ state update ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਦੀ ਹੈ। React ਕੁਝ ਦਰਜਨ ਚੱਕਰਾਂ ਤੱਕ ਇਸ ਨੂੰ ਸਹਿ ਲੈਂਦਾ ਹੈ, ਫਿਰ ਬ੍ਰਾਊਜ਼ਰ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਫ੍ਰੀਜ਼ ਹੋਣ ਤੋਂ ਬਚਾਉਣ ਲਈ maximum depth error ਦਿਖਾ ਦਿੰਦਾ ਹੈ।
State 'ਤੇ ਇੱਕ ਨਜ਼ਰ
ਲੂਪ ਦਾ ਵਿਸ਼ਲੇਸ਼ਣ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ, ਯਾਦ ਕਰੋ ਕਿ useState hook ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ। ਇਹ ਤੁਹਾਨੂੰ ਬਿਲਕੁਲ ਦੋ ਚੀਜ਼ਾਂ ਦਿੰਦਾ ਹੈ: ਇੱਕ ਵੇਰੀਏਬਲ (variable) ਜੋ ਮੌਜੂਦਾ ਮੁੱਲ (value) ਨੂੰ ਰੱਖਦਾ ਹੈ, ਅਤੇ ਇੱਕ ਫੰਕਸ਼ਨ ਜੋ ਉਸ ਮੁੱਲ ਨੂੰ ਬਦਲਣ ਲਈ ਹੁੰਦਾ ਹੈ।
const MessageComponent = () => {
const [message, setMessage] = useState('Welcome');
return <h1>{message}</h1>;
};
ਇੱਥੇ, ਪਹਿਲੇ render 'ਤੇ message 'Welcome' ਹੈ। ਜੇਕਰ ਤੁਸੀਂ ਬਾਅਦ ਵਿੱਚ setMessage('Goodbye') ਕਾਲ ਕਰਦੇ ਹੋ, ਤਾਂ React ਬਦਲਾਅ ਨੂੰ ਨੋਟ ਕਰਦਾ ਹੈ, MessageComponent ਨੂੰ ਦੁਬਾਰਾ ਕਾਲ ਕਰਦਾ ਹੈ, ਅਤੇ ਹੁਣ UI "Goodbye" ਦਿਖਾਉਂਦਾ ਹੈ। ਸਭ ਕੁਝ ਠੀਕ ਹੈ ਕਿਉਂਕਿ component body ਦੇ ਅੰਦਰ ਕੁਝ ਵੀ setter ਨੂੰ ਆਪਣੇ ਆਪ ਕਾਲ ਨਹੀਂ ਕਰ ਰਿਹਾ ਹੈ। ਲੂਪ ਉਦੋਂ ਸ਼ੁਰੂ ਹੁੰਦਾ ਹੈ ਜਦੋਂ setter ਕਿਸੇ ਬਾਹਰੀ event ਤੋਂ ਬਿਨਾਂ render phase ਦੌਰਾਨ ਚੱਲ ਜਾਂਦਾ ਹੈ।
Body ਵਿੱਚ ਸਿੱਧਾ SetState ਕਾਲ ਕਰਨਾ
ਇੱਕ ਅਨੰਤ ਲੂਪ ਬਣਾਉਣ ਦਾ ਸਭ ਤੋਂ ਸਿੱਧਾ ਤਰੀਕਾ component body ਦੇ ਅੰਦਰ ਹੀ state setter ਫੰਕਸ਼ਨ ਨੂੰ ਕਾਲ ਕਰਨਾ ਹੈ। ਕਿਉਂਕਿ component body ਹਰ render 'ਤੇ ਚੱਲਦੀ ਹੈ, ਇਸ ਲਈ setter ਹਰ render 'ਤੇ ਚੱਲਦਾ ਹੈ। ਉਹ ਨਵੀਂ state update ਇੱਕ ਹੋਰ render ਦਾ ਕਾਰਨ ਬਣਦੀ ਹੈ। ਇਹ ਚੱਕਰ ਹਮੇਸ਼ਾ ਲਈ ਚੱਲਦਾ ਰਹਿੰਦਾ ਹੈ।
ਗਲਤੀ ਕੁਝ ਇਸ ਤਰ੍ਹਾਂ ਦਿਖਾਈ ਦਿੰਦੀ ਹੈ:
const Counter = () => {
const [count, setCount] = useState(0);
setCount(count + 1);
return <div>{count}</div>;
};
ਹਰ ਵਾਰ ਜਦੋਂ Counter render ਹੁੰਦਾ ਹੈ, ਇਹ count ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ। React ਨਵਾਂ ਨੰਬਰ ਦਿਖਾਉਣ ਲਈ ਦੁਬਾਰਾ render ਕਰਦਾ ਹੈ, ਫਿਰ ਤੋਂ setCount(count + 1) ਦੇਖਦਾ ਹੈ, ਅਤੇ ਇੱਕ ਵਾਰ ਫਿਰ ਵਧਾ ਦਿੰਦਾ ਹੈ। ਇਸ ਦਾ ਹੱਲ ਸਿੱਧਾ ਹੈ: ਰੈਂਡਰ ਦੌਰਾਨ ਆਪਣੇ component ਦੇ top level 'ਤੇ ਕਦੇ ਵੀ state setter ਨੂੰ ਕਾਲ ਨਾ ਕਰੋ। State updates ਨੂੰ ਯੂਜ਼ਰ events ਜਾਂ side effects ਦਾ ਜਵਾਬ ਦੇਣਾ ਚਾਹੀਦਾ ਹੈ, ਸਕ੍ਰੀਨ 'ਤੇ ਚਿੱਤਰ ਉਲੀਕਣ (painting) ਦੇ ਕੰਮ ਦਾ ਨਹੀਂ। ਇਸ ਦੀ ਬਜਾਏ ਉਸ update ਨੂੰ ਇੱਕ event handler ਵਿੱਚ ਲੈ ਜਾਓ:
const Counter = () => {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
};
Render ਦੌਰਾਨ setters ਨੂੰ ਕਾਲ ਕਰਨ ਦਾ ਇੱਕੋ ਇੱਕ ਅਪਵਾਦ ਉਦੋਂ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ props ਤੋਂ ਨਵੀਂ state ਦੀ ਗਣਨਾ (computing) ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਅਤੇ ਉਦੋਂ ਵੀ ਤੁਹਾਨੂੰ ਇੱਕ ਵੱਖਰੇ ਪੈਟਰਨ ਦੀ ਵਰਤੋਂ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ, ਜਿਵੇਂ ਕਿ ਮੁੱਲ ਨੂੰ ਸਿੱਧੇ ਤੌਰ 'ਤੇ ਕੱਢਣਾ (deriving) ਜਾਂ ਜਾਣਬੁੱਝ ਕੇ useEffect ਦੀ ਵਰਤੋਂ ਕਰਨਾ।
Reference ਦੀ ਬਜਾਏ Function Call Pass ਕਰਨਾ
ਇੱਕ ਹੋਰ ਆਮ ਕਾਰਨ JSX ਵਿੱਚ ਇੱਕ ਬਾਰੀਕ ਗਲਤੀ (typo) ਹੈ। ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ event handler ਲਗਾਉਂਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਫੰਕਸ਼ਨ ਨੂੰ ਖੁਦ pass ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਜੇਕਰ ਤੁਸੀਂ ਗਲਤੀ ਨਾਲ JSX ਵਿੱਚ ਹੀ ਫੰਕਸ਼ਨ ਨੂੰ ਕਾਲ (invoke) ਕਰ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਇਹ render cycle ਦੌਰਾਨ ਤੁਰੰਤ ਚੱਲ ਜਾਂਦਾ ਹੈ।
const Toggle = () => {
const [isOn, setIsOn] = useState(false);
const handleToggle = () => setIsOn(!isOn);
return <button onClick={handleToggle()}>Toggle</button>;
};
Parentheses ਦੇ ਨਾਲ handleToggle() ਲਿਖ ਕੇ, ਤੁਸੀਂ React ਨੂੰ ਅਜਿਹਾ ਫੰਕਸ਼ਨ ਨਹੀਂ ਦੇ ਰਹੇ ਜੋ ਯੂਜ਼ਰ ਦੇ ਕਲਿੱਕ ਕਰਨ 'ਤੇ ਬਾਅਦ ਵਿੱਚ ਕਾਲ ਕੀਤਾ ਜਾ ਸਕੇ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਅਜੇ ਕਾਲ ਕਰ ਰਹੇ ਹੋ ਜਦੋਂ React virtual DOM ਬਣਾ ਰਿਹਾ ਹੁੰਦਾ ਹੈ। ਕਿਉਂਕਿ handleToggle state ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ, ਇਸ ਲਈ component re-render ਹੁੰਦਾ ਹੈ। ਉਸ re-render ਦੌਰਾਨ, React ਫਿਰ ਤੋਂ handleToggle() ਦੇਖਦਾ ਹੈ ਅਤੇ ਇਸ ਨੂੰ ਦੁਬਾਰਾ ਕਾਲ ਕਰਦਾ ਹੈ। ਇਹ ਲੂਪ ਕਦੇ ਖਤਮ ਨਹੀਂ ਹੁੰਦਾ। ਸਹੀ ਵਰਜ਼ਨ ਵਿੱਚ parentheses ਹਟਾ ਦਿੱਤੇ ਜਾਂਦੇ ਹਨ:
return <button onClick={handleToggle}>Toggle</button>;
ਜੇਕਰ ਤੁਹਾਨੂੰ arguments pass ਕਰਨ ਦੀ ਲੋੜ ਹੈ, ਤਾਂ ਕਾਲ ਨੂੰ ਇੱਕ anonymous function ਵਿੱਚ ਲਪੇਟ ਦਿਓ:
return <button onClick={() => handleToggle(true)}>Switch On</button>;
ਇਹ ਫਰਕ refactoring ਦੌਰਾਨ ਤਜਰਬੇਕਾਰ ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਵੀ ਉਲਝਾ ਸਕਦਾ ਹੈ। ਉਹਨਾਂ parentheses 'ਤੇ ਨਜ਼ਰ ਰੱਖੋ।
useEffect Dependency Trap
Effects, data fetch ਕਰਨ, browser APIs ਨਾਲ sync ਕਰਨ, ਜਾਂ ਮੈਨੂਅਲ ਤੌਰ 'ਤੇ DOM ਨੂੰ ਹੱਥ ਲਗਾਉਣ (manipulating) ਵਰਗੇ side effects ਲਈ ਸਹੀ ਜਗ੍ਹਾ ਹਨ। ਪਰ useEffect ਉਦੋਂ ਚੱਲਦਾ ਹੈ ਜਦੋਂ React render ਨੂੰ ਸਕ੍ਰੀਨ 'ਤੇ commit ਕਰ ਦਿੰਦਾ ਹੈ। ਜੇਕਰ ਤੁਹਾਡਾ effect state ਨੂੰ ਅਪਡੇਟ ਕਰਦਾ ਹੈ, ਤਾਂ React re-render ਕਰੇਗਾ। ਆਮ ਤੌਰ 'ਤੇ ਇਹ ਠੀਕ ਹੈ। ਇਹ ਉਦ
ਇਸ ਟੁੱਟੇ ਹੋਏ ਪੈਟਰਨ 'ਤੇ ਵਿਚਾਰ ਕਰੋ:
const UserProfile = () => {
const [user, setUser] = useState({});
useEffect(() => {
setUser({ name: 'Ada', role: 'Admin' });
});
return <div>{user.name}</div>;
};
ਕਿਉਂਕਿ ਇੱਥੇ ਕੋਈ dependency array ਨਹੀਂ ਹੈ, ਇਸ ਲਈ ਇਹ effect ਹਰ ਇੱਕ render ਤੋਂ ਬਾਅਦ ਚੱਲਦਾ ਹੈ। ਇਹ user ਨੂੰ ਸੈੱਟ ਕਰਦਾ ਹੈ, ਜੋ ਇੱਕ render ਨੂੰ ਟ੍ਰਿਗਰ ਕਰਦਾ ਹੈ। ਉਸ render ਤੋਂ ਬਾਅਦ, effect ਦੁਬਾਰਾ ਚੱਲਦਾ ਹੈ ਅਤੇ user ਨੂੰ ਦੁਬਾਰਾ ਸੈੱਟ ਕਰਦਾ ਹੈ। React ਇਸ ਚੱਕਰ ਨੂੰ ਪਛਾਣ ਲੈਂਦਾ ਹੈ ਅਤੇ error ਸੁੱਟ ਦਿੰਦਾ ਹੈ।
ਇਸਦਾ ਹੱਲ React ਨੂੰ ਇਹ ਦੱਸਣਾ ਹੈ ਕਿ effect ਨੂੰ ਅਸਲ ਵਿੱਚ ਕਦੋਂ ਚੱਲਣ ਦੀ ਲੋੜ ਹੈ, ਇਸ ਲਈ ਇੱਕ ਸਹੀ dependency array ਪ੍ਰਦਾਨ ਕਰੋ। ਜੇਕਰ effect ਨੂੰ ਸਿਰਫ਼ mount ਹੋਣ ਵੇਲੇ ਇੱਕ ਵਾਰ ਚੱਲਣਾ ਚਾਹੀਦਾ ਹੈ, ਤਾਂ ਇੱਕ ਖਾਲੀ array pass ਕਰੋ:
useEffect(() => {
setUser({ name: 'Ada', role: 'Admin' });
}, []);
ਜੇਕਰ effect ਕਿਸੇ prop ਜਾਂ state ਦੇ ਹਿੱਸੇ 'ਤੇ ਨਿਰਭਰ ਕਰਦਾ ਹੈ, ਤਾਂ array ਵਿੱਚ ਸਿਰਫ਼ ਉਸੇ variable ਨੂੰ ਸ਼ਾਮਲ ਕਰੋ। ਹਾਲਾਂਕਿ, ਸਾਵਧਾਨ ਰਹੋ। ਅਜਿਹਾ variable ਸ਼ਾਮਲ ਕਰਨਾ ਜੋ ਹਰ render 'ਤੇ ਬਦਲਦਾ ਹੈ, ਸਿਰਫ਼ ਇੱਕ ਵੱਖਰੇ ਤਰੀਕੇ ਨਾਲ ਉਹੀ ਲੂਪ (loop) ਦੁਬਾਰਾ ਬਣਾ ਦੇਵੇਗਾ। ਉਦਾਹਰਨ ਲਈ, ਜੇਕਰ ਤੁਸੀਂ dependencies ਵਿੱਚ ਇੱਕ object literal ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ ਅਤੇ ਉਹ object ਹਰ parent render 'ਤੇ ਦੁਬਾਰਾ ਬਣਦਾ ਹੈ, ਤਾਂ effect ਲਗਾਤਾਰ ਚੱਲਦਾ ਰਹੇਗਾ। ਅਜਿਹੇ ਮਾਮਲਿਆਂ ਵਿੱਚ, ਤੁਹਾਨੂੰ object creation ਨੂੰ component ਤੋਂ ਬਾਹਰ ਲਿਜਾਣ ਜਾਂ ਉਸਨੂੰ memoize ਕਰਨ ਦੀ ਲੋੜ ਹੋ ਸਕਦੀ ਹੈ।
Practical Debugging Steps
ਜਦੋਂ ਤੁਹਾਨੂੰ ਇਹ error ਆਉਂਦਾ ਹੈ, ਤਾਂ stack trace ਬਹੁਤ ਜ਼ਿਆਦਾ ਉਲਝਣ ਵਾਲਾ ਲੱਗ ਸਕਦਾ ਹੈ ਕਿਉਂਕਿ React ਪਹਿਲਾਂ ਹੀ ਦਰਜਨਾਂ ਵਾਰ ਇਹ ਚੱਕਰ ਦੁਹਰਾ ਚੁੱਕਾ ਹੁੰਦਾ ਹੈ। ਇਹ ਪਤਾ ਲਗਾਉਣ ਲਈ ਕਿ ਕਿਹੜਾ component ਵਾਰ-ਵਾਰ ਨਾਮ ਲੈ ਰਿਹਾ ਹੈ, trace ਦੇ ਉੱਪਰਲੇ ਹਿੱਸੇ ਨੂੰ ਪੜ੍ਹਨਾ ਸ਼ੁਰੂ ਕਰੋ। ਫਿਰ ਇਹਨਾਂ ਤਿੰਨਾਂ ਥਾਵਾਂ 'ਤੇ state setters ਲੱਭੋ:
- Component ਦੀ ਮੁੱਖ body, ਕਿਸੇ ਵੀ handler ਜਾਂ hook ਤੋਂ ਬਾਹਰ।
- JSX event attributes ਜਿੱਥੇ ਤੁਸੀਂ
handlerਦੀ ਬਜਾਏhandler()ਲਿਖਿਆ ਹੋ ਸਕਦਾ ਹੈ। useEffecthooks ਜਿਨ੍ਹਾਂ ਵਿੱਚ dependency array ਦੀ ਕਮੀ ਹੈ ਜਾਂ ਜੋ ਅਸਥਿਰ (unstable) references 'ਤੇ ਨਿਰਭਰ ਕਰਦੇ ਹਨ।
ਜਦੋਂ ਤੱਕ error ਰੁਕ ਨਹੀਂ ਜਾਂਦਾ, ਉਦੋਂ ਤੱਕ ਹਰੇਕ state setter ਨੂੰ ਅਸਥਾਈ ਤੌਰ 'ਤੇ comment out ਕਰ ਦਿਓ। ਇਹ ਤੁਹਾਨੂੰ ਦੱਸੇਗਾ ਕਿ ਕਿਹੜਾ update ਦੋਸ਼ੀ ਹੈ। ਜੇਕਰ setter ਕਿਸੇ effect ਦੇ ਅੰਦਰ ਹੈ, ਤਾਂ ਆਪਣੇ ਆਪ ਨੂੰ ਪੁੱਛੋ ਕਿ ਕੀ ਤੁਹਾਨੂੰ ਉੱਥੇ state ਦੀ ਲੋੜ ਹੈ ਵੀ। ਕਈ ਵਾਰ developers effect ਦੇ ਅੰਦਰ props ਤੋਂ local state ਸੈੱਟ ਕਰਦੇ ਹਨ ਜਦੋਂ ਕਿ ਉਹ JSX ਵਿੱਚ ਸਿੱਧੇ ਤੌਰ 'ਤੇ prop ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਸਨ।
The Real Takeaway
Maximum update depth error ਕੋਈ ਰਹੱਸਮਈ React bug ਨਹੀਂ ਹੈ। ਇਹ ਇੱਕ ਸੁਰੱਖਿਆ ਜਾਲ (safety net) ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਤੁਹਾਡਾ component ਕਿਸੇ ਬਾਹਰੀ ਸਿਗਨਲ ਦੀ ਉਡੀਕ ਕਰਨ ਦੀ ਬਜਾਏ ਆਪਣੇ ਆਪ ਨੂੰ re-render ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ। Renders ਨੂੰ ਅਜਿਹੇ events ਵਜੋਂ ਦੇਖਣ ਦੀ ਆਦਤ ਛੱਡੋ ਜੋ ਹੋਰ state ਪੈਦਾ ਕਰਨੇ ਚਾਹੀਦੇ ਹਨ। Renders ਨੂੰ state ਦੇ ਸ਼ੁੱਧ ਨਤੀਜੇ ਵਜੋਂ ਦੇਖੋ, ਨਾ ਕਿ ਕਾਰਨ ਵਜੋਂ। State updates ਨੂੰ event handlers, callbacks, ਜਾਂ ਸਾਵਧਾਨੀ ਨਾਲ ਚੁਣੇ ਗਏ dependencies ਵਾਲੇ effects ਦੇ ਅੰਦਰ ਰੱਖੋ, ਅਤੇ ਤੁਸੀਂ ਇਹ error ਦੁਬਾਰਾ ਕਦੇ ਨਹੀਂ ਦੇਖੋਗੇ।
