ನೀವು ಪುಟವನ್ನು ರಿಫ್ರೆಶ್ ಮಾಡುತ್ತೀರಿ ಮತ್ತು ಪರದೆ ಖಾಲಿ ಇರುತ್ತದೆ. ಅಥವಾ ಬಹುಶಃ ಒಂದು ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡಿದ್ದಕ್ಕೆ ನಿಮ್ಮ CPU ಫ್ಯಾನ್ ವೇಗವಾಗಿ ತಿರುಗಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ. ನಂತರ ಕನ್ಸೋಲ್‌ನಲ್ಲಿ ಆ ಭಯಾನಕ ಎಚ್ಚರಿಕೆ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ: Maximum update depth exceeded. ನಿಮ್ಮ component ಒಂದು ಅನಂತ ಲೂಪ್‌ನಲ್ಲಿ (infinite loop) ಸಿಲುಕಿಕೊಂಡಿರುವುದರಿಂದ React ಬ್ರೇಕ್ ಹಾಕಿದೆ. ಇದು React ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ ಕಂಡುಬರುವ ಅತ್ಯಂತ ಸಾಮಾನ್ಯ ದೋಷಗಳಲ್ಲಿ ಒಂದಾಗಿದೆ ಮತ್ತು ಇದು ಸಾಮಾನ್ಯವಾಗಿ ನಿಮ್ಮ ಕೋಡ್ ಯಾವಾಗ ಕಾರ್ಯಗತಗೊಳ್ಳುತ್ತದೆ ಎಂಬ ಬಗ್ಗೆ ಇರುವ ಸರಳ ತಪ್ಪು ತಿಳುವಳಿಕೆಯಿಂದ ಉಂಟಾಗುತ್ತದೆ.

ಇದನ್ನು ಸರಿಪಡಿಸಲು, ಒಂದು render ಯಾವಾಗ re-render ಆಗುತ್ತದೆ ಮತ್ತು state ಬದಲಾವಣೆಗಳು ಏಕೆ render path ನಿಂದ ಹೊರಗೆ ಇರಬೇಕು ಎಂಬುದನ್ನು ನೀವು ನಿಖರವಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಬೇಕಾಗುತ್ತದೆ.

React ನಿಮ್ಮ Component ಅನ್ನು ಹೇಗೆ Render ಮಾಡುತ್ತದೆ

React ಬಳಕೆದಾರರ ಇಂಟರ್ಫೇಸ್‌ಗಳನ್ನು (user interfaces) components ಮೂಲಕ ನಿರ್ಮಿಸುತ್ತದೆ. ಆಧುನಿಕ React ನಲ್ಲಿ, ಆ components ಗಳು function ಗಳಾಗಿವೆ. ಪ್ರತಿ ಬಾರಿ React ನಿಮ್ಮ component ಅನ್ನು ಪರದೆಯ ಮೇಲೆ ತೋರಿಸಬೇಕಾದಾಗ, ಅದು ಕೇವಲ ಆ function ಅನ್ನು ಕರೆಯುತ್ತದೆ. Function ಒಳಗೆ, renders ಗಳ ನಡುವೆ ವಿಷಯಗಳನ್ನು ನೆನಪಿಟ್ಟುಕೊಳ್ಳಲು ನೀವು state ಅನ್ನು ಬಳಸಬಹುದು. State ಎಂಬುದು ಯಾವ ಡೇಟಾ component ಗೆ ಸೇರಿದ್ದು ಮತ್ತು ಮುಖ್ಯವಾಗಿ, ಯಾವಾಗ ಏನಾದರೂ ಬದಲಾಗಿದೆ ಮತ್ತು UI ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಬೇಕಾಗಿದೆ ಎಂಬುದನ್ನು React ಗೆ ತಿಳಿಸುತ್ತದೆ.

State ಬದಲಾದಾಗ, React ಹೊಸ render ಅನ್ನು ನಿಗದಿಪಡಿಸುತ್ತದೆ. Component function ಮತ್ತೆ ರನ್ ಆಗುತ್ತದೆ, ಹೊಸ JSX ಅನ್ನು ರಿಟರ್ನ್ ಮಾಡುತ್ತದೆ ಮತ್ತು React ಅದಕ್ಕೆ ಅನುಗುಣವಾಗಿ DOM ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಬಳಕೆಯಲ್ಲಿ, ಈ ಚಕ್ರವು ಹಾನಿಕಾರಕವಲ್ಲ. ನೀವು ಒಂದು ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡುತ್ತೀರಿ, ಒಂದು event handler state ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡುತ್ತದೆ, React ಒಮ್ಮೆ re-renders ಆಗುತ್ತದೆ ಮತ್ತು ಬಳಕೆದಾರರು ಹೊಸ ಪಠ್ಯ ಅಥವಾ ಬಣ್ಣವನ್ನು ನೋಡುತ್ತಾರೆ.

ಒಂದು render ತನ್ನಷ್ಟಕ್ಕೆ ತಾನೇ ಮತ್ತೊಂದು state update ಅನ್ನು ಪ್ರಚೋದಿಸಿದಾಗ ಈ ದೋಷ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಆ ಹೊಸ state update ಮತ್ತೊಂದು render ಅನ್ನು ಪ್ರಚೋದಿಸುತ್ತದೆ, ಅದು ಮತ್ತೊಂದು state update ಅನ್ನು ಪ್ರಚೋದಿಸುತ್ತದೆ. React ಕೆಲವು ಡಜನ್ ಚಕ್ರಗಳವರೆಗೆ ಇದನ್ನು ಸಹಿಸಿಕೊಳ್ಳುತ್ತದೆ, ನಂತರ ಬ್ರೌಸರ್ ಸಂಪೂರ್ಣವಾಗಿ ಫ್ರೀಜ್ ಆಗದಂತೆ ತಡೆಯಲು maximum depth error ಅನ್ನು ಎಸೆಯುತ್ತದೆ.

State ಬಗ್ಗೆ ಒಂದು ಸಂಕ್ಷಿಪ್ತ ನೋಟ

ಲೂಪ್ ಅನ್ನು ವಿಶ್ಲೇಷಿಸುವ ಮೊದಲು, useState hook ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ ಎಂಬುದನ್ನು ನೆನಪಿಸಿಕೊಳ್ಳಿ. ಇದು ನಿಮಗೆ ನಿಖರವಾಗಿ ಎರಡು ವಿಷಯಗಳನ್ನು ನೀಡುತ್ತದೆ: ಪ್ರಸ್ತುತ ಮೌಲ್ಯವನ್ನು ಹೊಂದಿರುವ ಒಂದು variable ಮತ್ತು ಆ ಮೌಲ್ಯವನ್ನು ಬದಲಾಯಿಸಲು ಒಂದು function.

const MessageComponent = () => {
  const [message, setMessage] = useState('Welcome');

  return <h1>{message}</h1>;
};

ಇಲ್ಲಿ, ಮೊದಲ render ನಲ್ಲಿ message ಎಂಬುದು 'Welcome' ಆಗಿದೆ. ನೀವು ನಂತರ setMessage('Goodbye') ಎಂದು ಕರೆಯಲು, React ಬದಲಾವಣೆಯನ್ನು ಗಮನಿಸುತ್ತದೆ, MessageComponent ಅನ್ನು ಮತ್ತೆ ಕರೆಯುತ್ತದೆ ಮತ್ತು ಈಗ UI "Goodbye" ಎಂದು ತೋರಿಸುತ್ತದೆ. ಇಲ್ಲಿ ಎಲ್ಲವೂ ಸರಿಯಾಗಿದೆ ಏಕೆಂದರೆ component body ನಲ್ಲಿ ಯಾವುದೂ ಸ್ವಯಂಚಾಲಿತವಾಗಿ setter ಅನ್ನು ಕರೆಯುತ್ತಿಲ್ಲ. ಬಾಹ್ಯ event ಇಲ್ಲದೆ render phase ಸಮಯದಲ್ಲಿ setter ಕಾರ್ಯಗತಗೊಂಡಾಗ ಲೂಪ್ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ.

Body ನಲ್ಲಿ ನೇರವಾಗಿ SetState ಅನ್ನು ಕರೆಯುವುದು

ಅನಂತ ಲೂಪ್ ಅನ್ನು ರಚಿಸಲು ಅತ್ಯಂತ ನೇರವಾದ ಮಾರ್ಗವೆಂದರೆ component body ಒಳಗೆ ನೇರವಾಗಿ state setter function ಅನ್ನು ಕರೆಯುವುದು. 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) ಅನ್ನು ನೋಡುತ್ತದೆ ಮತ್ತು ಮತ್ತೊಮ್ಮೆ ಹೆಚ್ಚಿಸುತ್ತದೆ. ಇದಕ್ಕೆ ಪರಿಹಾರ ಸರಳವಾಗಿದೆ: render ಮಾಡುವಾಗ ನಿಮ್ಮ component ನ top level ನಲ್ಲಿ ಎಂದಿಗೂ state setter ಅನ್ನು ಕರೆಯಬೇಡಿ. State updates ಗಳು ಬಳಕೆದಾರರ events ಅಥವಾ side effects ಗೆ ಪ್ರತಿಕ್ರಿಯಿಸಬೇಕೇ ಹೊರತು, ಪರದೆಯನ್ನು ಬಿಡಿಸುವ (painting the screen) ಕ್ರಿಯೆಗೆ ಅಲ್ಲ. ಆ update ಅನ್ನು event handler ಒಳಗೆ ವರ್ಗಾಯಿಸಿ:

const Counter = () => {
  const [count, setCount] = useState(0);

  return <button onClick={() => setCount(count + 1)}>{count}</button>;
};

Render ಮಾಡುವಾಗ setters ಅನ್ನು ಕರೆಯಲು ಇರುವ ಏಕೈಕ ವಿನಾಯಿತಿ ಎಂದರೆ ನೀವು props ನಿಂದ ಹೊಸ state ಅನ್ನು ಲೆಕ್ಕಹಾಕುತ್ತಿದ್ದರೆ (computing), ಮತ್ತು ಅಂತಹ ಸಂದರ್ಭದಲ್ಲೂ ನೀವು ಮೌಲ್ಯವನ್ನು ನೇರವಾಗಿ ಪಡೆಯುವ ಅಥವಾ ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ useEffect ಬಳಸುವಂತಹ ವಿಭಿನ್ನ ಮಾದರಿಯನ್ನು ಬಳಸಬೇಕು.

Reference ಬದಲಿಗೆ Function Call ಅನ್ನು ಕಳುಹಿಸುವುದು

ಮತ್ತೊಂದು ಸಾಮಾನ್ಯ ಕಾರಣವೆಂದರೆ ಸಣ್ಣ JSX typo. ನೀವು ಒಂದು event handler ಅನ್ನು ಅಂಟಿಸಿದಾಗ (attach), ನೀವು function ಅನ್ನು ಮಾತ್ರ ಕಳುಹಿಸಬೇಕಾಗುತ್ತದೆ. ನೀವು ಅಚಾನಕ್ ಆಗಿ JSX ನಲ್ಲಿಯೇ ಆ function ಅನ್ನು ಕರೆಯಲು (invoke) ಪ್ರಯತ್ನಿಸಿದರೆ, ಅದು render cycle ಸಮಯದಲ್ಲಿ ತಕ್ಷಣವೇ ರನ್ ಆಗುತ್ತದೆ.

const Toggle = () => {
  const [isOn, setIsOn] = useState(false);

  const handleToggle = () => setIsOn(!isOn);

  return <button onClick={handleToggle()}>Toggle</button>;
};

ಬ್ರಾಕೆಟ್‌ಗಳೊಂದಿಗೆ handleToggle() ಎಂದು ಬರೆಯುವ ಮೂಲಕ, ಬಳಕೆದಾರರು ಕ್ಲಿಕ್ ಮಾಡಿದಾಗ ಕರೆಯಲು ನೀವು React ಗೆ function ಅನ್ನು ನೀಡುತ್ತಿಲ್ಲ. ಬದಲಾಗಿ, React virtual DOM ಅನ್ನು ನಿರ್ಮಿಸುತ್ತಿರುವಾಗಲೇ ನೀವು ಅದನ್ನು ಈಗಲೇ ಕರೆಯುತ್ತಿದ್ದೀರಿ. handleToggle state ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡುವುದರಿಂದ, component re-renders ಆಗುತ್ತದೆ. ಆ re-render ಸಮಯದಲ್ಲಿ, React ಮತ್ತೆ handleToggle() ಅನ್ನು ನೋಡಿ ಅದನ್ನು ಮತ್ತೆ ಕರೆಯುತ್ತದೆ. ಈ ಲೂಪ್ ಎಂದಿಗೂ ಕೊನೆಗೊಳ್ಳುವುದಿಲ್ಲ. ಸರಿಯಾದ ಆವೃತ್ತಿಯು ಬ್ರಾಕೆಟ್‌ಗಳನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ:

return <button onClick={handleToggle}>Toggle</button>;

ನಿಮಗೆ arguments ಕಳುಹಿಸಬೇಕಿದ್ದರೆ, ಆ call ಅನ್ನು ಒಂದು anonymous function ಒಳಗೆ ಸುತ್ತಿ (wrap):

return <button onClick={() => handleToggle(true)}>Switch On</button>;

Refactoring ಮಾಡುವಾಗ ಅನುಭವಿ ಡೆವಲಪರ್‌ಗಳು ಕೂಡ ಈ ವ್ಯತ್ಯಾಸದಿಂದ ಗೊಂದಲಕ್ಕೊಳಗಾಗುತ್ತಾರೆ. ಆ ಬ್ರಾಕೆಟ್‌ಗಳ ಬಗ್ಗೆ ಗಮನವಿರಲಿ.

useEffect Dependency Trap

ಡೇಟಾವನ್ನು ಪಡೆಯುವುದು (fetching data), browser APIs ಗಳೊಂದಿಗೆ ಸಿಂಕ್ ಮಾಡುವುದು ಅಥವಾ ಮ್ಯಾನುಯಲ್ ಆಗಿ DOM ಅನ್ನು ನಿರ್ವಹಿಸುವುದು போன்ற side effects ಗಾಗಿ effects ಸರಿಯಾದ ಸ್ಥಳವಾಗಿದೆ. ಆದರೆ useEffect, React ತನ್ನ render ಅನ್ನು ಪರದೆಯ ಮೇಲೆ ಕಮಿಟ್ ಮಾಡಿದ ನಂತರ ರನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ effect state ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಿದರೆ, React re-render ಆಗುತ್ತದೆ. ಸಾಮಾನ್ಯವಾಗಿ ಅದು ಸರಿಯೇ. ಆದರೆ effect ಪ್ರತಿ render ನಂತರ ರನ್ ಆಗಿ ಮತ್ತು ಯಾವಾಗಲೂ ಒಂದೇ state ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಿದಾಗ ಅದು ಲೂಪ್ ಆಗುತ್ತದೆ.

ಈ ಕೆಳಗಿನ ದೋಷಪೂರಿತ ಮಾದರಿಯನ್ನು ಗಮನಿಸಿ:

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 ಅನ್ನು ತೋರಿಸುತ್ತದೆ.

ಸರಿಯಾದ dependency array ಅನ್ನು ಒದಗಿಸುವ ಮೂಲಕ effect ಯಾವಾಗ ನಿಜವಾಗಿಯೂ ಚಲಿಸಬೇಕೆಂದು React ಗೆ ತಿಳಿಸುವುದೇ ಇದಕ್ಕೆ ಪರಿಹಾರ. ಒಂದು ವೇಳೆ effect ಕೇವಲ mount ಆದಾಗ ಮಾತ್ರ ಚಲಿಸಬೇಕೆಂದಿದ್ದರೆ, ಖಾಲಿ array ಅನ್ನು ನೀಡಿ:

useEffect(() => {
  setUser({ name: 'Ada', role: 'Admin' });
}, []);

ಒಂದು ವೇಳೆ effect ಯಾವುದಾದರೂ prop ಅಥವಾ state ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿದ್ದರೆ, ಆ variable ಅನ್ನು ಮಾತ್ರ array ನಲ್ಲಿ ಸೇರಿಸಿ. ಆದರೆ ಎಚ್ಚರವಿರಲಿ. ಪ್ರತಿ render ನಲ್ಲಿ ಬದಲಾಗುವ variable ಅನ್ನು ಸೇರಿಸುವುದು ಅದೇ loop ಅನ್ನು ಬೇರೆ ರೀತಿಯಲ್ಲಿ ಮತ್ತೆ ಸೃಷ್ಟಿಸುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ನೀವು dependencies ನಲ್ಲಿ ಒಂದು object literal ಅನ್ನು ಸೇರಿಸಿದರೆ ಮತ್ತು ಆ object ಪ್ರತಿ parent render ನಲ್ಲಿ ಮತ್ತೆ ಸೃಷ್ಟಿಯಾಗುತ್ತಿದ್ದರೆ, effect ಅಂತ್ಯವಿಲ್ಲದೆ ಚಲಿಸುತ್ತಲೇ ಇರುತ್ತದೆ. ಅಂತಹ ಸಂದರ್ಭಗಳಲ್ಲಿ, ನೀವು object ರಚನೆಯನ್ನು component ಹೊರಗೆ ಸ್ಥಳಾಂತರಿಸಬೇಕಾಗಬಹುದು ಅಥವಾ ಅದನ್ನು memoize ಮಾಡಬೇಕಾಗಬಹುದು.

ಪ್ರಾಯೋಗಿಕ ಡಿಬಗ್ಗಿಂಗ್ ಹಂತಗಳು

ಈ error ಬಂದಾಗ, stack trace ಗೊಂದಲಮಯವಾಗಿ ಕಾಣಿಸಬಹುದು ಏಕೆಂದರೆ React ಈಗಾಗಲೇ ಈ ಚಕ್ರವನ್ನು ಡಜನ್‌ಗಟ್ಟಲೆ ಬಾರಿ ಪುನರಾವರ್ತಿಸಿರುತ್ತದೆ. ಯಾವ component ಪದೇ ಪದೇ ಹೆಸರಿಸಲ್ಪಟ್ಟಿದೆ ಎಂಬುದನ್ನು ಕಂಡುಹಿಡಿಯಲು trace ನ ಮೇಲ್ಭಾಗವನ್ನು ಓದುವ ಮೂಲಕ ಪ್ರಾರಂಭಿಸಿ. ನಂತರ ಈ ಮೂರು ಸ್ಥಳಗಳಲ್ಲಿ state setters ಗಳಿಗಾಗಿ ಹುಡುಕಿ:

  1. ಯಾವುದೇ handler ಅಥವಾ hook ಹೊರಗೆ ಇರುವ component ನ ಮುಖ್ಯ ಭಾಗ (main body).
  2. JSX event attributes ಗಳಲ್ಲಿ ನೀವು handler ಬದಲಿಗೆ handler() ಎಂದು ಬರೆದಿದ್ದೀರಾ ಎಂದು ಪರಿಶೀಲಿಸಿ.
  3. dependency array ಇಲ್ಲದ ಅಥವಾ ಅಸ್ಥಿರವಾದ (unstable) references ಮೇಲೆ ಅವಲಂಬಿತವಾಗಿರುವ useEffect hooks.

error ನಿಲ್ಲುವವರೆಗೆ ತಾತ್ಕಾಲಿಕವಾಗಿ ಪ್ರತಿಯೊಂದು state setter ಅನ್ನು comment out ಮಾಡಿ. ಇದು ಯಾವ update ತಪ್ಪಿಗೆ ಕಾರಣವಾಗಿದೆ ಎಂಬುದನ್ನು ನಿಖರವಾಗಿ ತಿಳಿಸುತ್ತದೆ. ಒಂದು ವೇಳೆ setter ಒಂದು effect ಒಳಗೆ ಇದ್ದರೆ, ನಿಮಗೆ ಅಲ್ಲಿ state ನ ಅಗತ್ಯವಿದೆಯೇ ಎಂದು ನಿಮ್ಮನ್ನೇ ಕೇಳಿಕೊಳ್ಳಿ. ಕೆಲವೊಮ್ಮೆ developers props ನಿಂದ ಸ್ಥಳೀಯ state ಅನ್ನು effect ಒಳಗೆ ಸೆಟ್ ಮಾಡುತ್ತಾರೆ, ಆದರೆ ಅವರು ನೇರವಾಗಿ JSX ನಲ್ಲಿ ಆ prop ಅನ್ನು ಬಳಸಬಹುದಿತ್ತು.

ನಿಜವಾದ ಪಾಠ

Maximum update depth error ಎಂಬುದು ಯಾವುದೋ ನಿಗೂಢ React bug ಅಲ್ಲ. ಇದು ಒಂದು ಸುರಕ್ಷತಾ ಜಾಲ (safety net). ಇದರರ್ಥ ನಿಮ್ಮ component ಬಾಹ್ಯ ಸಂಕೇತಕ್ಕಾಗಿ (external signal) ಕಾಯುವ ಬದಲು ತನ್ನನ್ನು ತಾನೇ ಮತ್ತೆ render ಮಾಡಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದೆ ಎಂದರ್ಥ. Render ಗಳನ್ನು ಹೆಚ್ಚಿನ state ಅನ್ನು ಉತ್ಪಾದಿಸುವ ಘಟನೆಗಳೆಂದು (events) ಪರಿಗಣಿಸುವ ಅಭ್ಯಾಸವನ್ನು ಬಿಡಿ. Render ಗಳನ್ನು state ನ ಪರಿಣಾಮಗಳೆಂದು (consequences) ಪರಿಗಣಿಸಿ, ಕಾರಣಗಳೆಂದು (causes) ಅಲ್ಲ. State updates ಗಳನ್ನು event handlers, callbacks ಅಥವಾ ಎಚ್ಚರಿಕೆಯಿಂದ ಆಯ್ಕೆ ಮಾಡಿದ dependencies ಹೊಂದಿರುವ effects ಒಳಗೆ ಇರಿಸಿ, ಆಗ ನೀವು ಈ error ಅನ್ನು ಮತ್ತೆ ಎಂದಿಗೂ ನೋಡುವುದಿಲ್ಲ.