<StrictMode> מאפשר לך למצוא באגים נפוצים ברכיבים שלך בשלב מוקדם במהלך הפיתוח.

<StrictMode>
<App />
</StrictMode>

הפניה

<StrictMode>

השתמש ב-StrictMode כדי לאפשר התנהגויות פיתוח נוספות ואזהרות עבור עץ הרכיבים בפנים:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);

ראה דוגמאות נוספות למטה.

מצב קפדני מאפשר את ההתנהגויות הבאות לפיתוח בלבד:

אבזרים

StrictMode לא מקבל props.

אזהרות

  • אין דרך לבטל את הסכמתך למצב קפדני בתוך עץ עטוף ב-<StrictMode>. זה נותן לך ביטחון שכל הרכיבים בתוך <StrictMode> מסומנים. אם שני צוותים שעובדים על מוצר אינם מסכימים אם הם מוצאים שההמחאות חשובות, הם צריכים להגיע לקונצנזוס או להעביר את <StrictMode> למטה בעץ.

שימוש

הפעלת מצב קפדני עבור האפליקציה כולה

מצב קפדני מאפשר בדיקות נוספות לפיתוח בלבד עבור כל עץ הרכיבים בתוך הרכיב <StrictMode>. בדיקות אלו עוזרות לך למצוא באגים נפוצים ברכיבים שלך בשלב מוקדם של תהליך הפיתוח.

כדי להפעיל מצב קפדני עבור כל האפליקציה שלך, עטוף את רכיב השורש שלך ב-<StrictMode> כשאתה מעבד אותו:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<App />
</StrictMode>
);

אנו ממליצים לעטוף את האפליקציה כולה במצב קפדני, במיוחד עבור אפליקציות חדשות שנוצרו. אם אתה use מסגרת שקוראת ל-createRoot עבורך, בדוק את התיעוד שלה כיצד להפעיל מצב קפדני.

למרות ש-Strict Mode בודקים פועלים רק בפיתוח, הם עוזרים לך למצוא באגים שכבר קיימים בקוד שלך אבל יכול להיות מסובך לשכפול מהימן בייצור. מצב קפדני מאפשר לך לתקן באגים לפני שה-users שלך מדווחים עליהם.

Note

מצב קפדני מאפשר את הבדיקות הבאות בפיתוח:

כל הבדיקות הללו הן לפיתוח בלבד ואינן משפיעות על בניית הייצור.


הפעלת מצב קפדני עבור חלק מהאפליקציה

אתה יכול גם להפעיל מצב קפדני עבור כל חלק ביישום שלך:

import { StrictMode } from 'react';

function App() {
return (
<>
<Header />
<StrictMode>
<main>
<Sidebar />
<Content />
</main>
</StrictMode>
<Footer />
</>
);
}

בדוגמה זו, בדיקות מצב קפדניות לא יפעלו כנגד הרכיבים Header וFooter. עם זאת, הם יפעלו על Sidebar וContent, כמו גם על כל הרכיבים שבתוכם, לא משנה כמה עמוק.


תיקון באגים שנמצאו על ידי רינדור כפול בפיתוח

React מניח שכל רכיב שאתה כותב הוא פונקציה טהורה. פירוש הדבר שרכיבי React שאתה כותב חייבים תמיד להחזיר את אותו JSX בהינתן אותם כניסות (props, state והקשר).

רכיבים המפרים את הכלל הזה מתנהגים בצורה בלתי צפויה ובאגים cause. כדי לעזור לך למצוא בטעות קוד לא טהור, Strict Mode קורא לחלק מהפונקציות שלך (רק אלו שאמורות להיות טהורות) פעמיים בפיתוח. זה כולל:

אם פונקציה טהורה, הפעלתה פעמיים לא משנה את התנהגותה מכיוון שפונקציה טהורה מפיקה את אותה תוצאה בכל פעם. עם זאת, אם פונקציה אינה טהורה (לדוגמה, היא משנה את הנתונים שהיא מקבלת), הפעלתה פעמיים נוטה להיות מורגשת (זה מה שהופך אותה לאטהורה!) זה עוזר לך לזהות ולתקן את הבאג מוקדם.

הנה דוגמה כדי להמחיש כיצד עיבוד כפול במצב קפדני עוזר לך למצוא באגים מוקדם.

רכיב StoryTray זה לוקח מערך של stories ומוסיף פריט “צור סיפור” אחרון בסוף:

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

יש טעות בקוד למעלה. עם זאת, קל לפספס מכיוון שהפלט הראשוני נראה נכון.

טעות זו תהפוך בולטת יותר אם הרכיב StoryTray יעבד מחדש מספר פעמים. לדוגמה, בוא נגרום ל-StoryTray לעבד מחדש עם צבע רקע שונה בכל פעם שאתה מרחף מעליו:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

שים לב איך בכל פעם שאתה מרחף מעל הרכיב StoryTray, “צור סיפור” יתווסף שוב לרשימה. הכוונה של הקוד הייתה להוסיף אותו פעם אחת בסוף. אבל StoryTray משנה ישירות את מערך stories מה-props. בכל פעם שStoryTray מעבד, הוא מוסיף “צור סיפור” שוב בסוף אותו מערך. במילים אחרות, StoryTray אינה פונקציה טהורה - הפעלתה מספר פעמים מניבה תוצאות שונות.

כדי לפתור בעיה זו, אתה יכול ליצור עותק של המערך, ולשנות את העותק במקום המקורי:

export default function StoryTray({ stories }) {
const items = stories.slice(); // Clone the array
// ✅ Good: Pushing into a new array
items.push({ id: 'create', label: 'Create Story' });

זה יהפוך את הפונקציה StoryTray לטהורה.](/learn/keeping-components-pure) בכל פעם שהיא נקראת, היא תשנה רק עותק חדש של המערך, ולא תשפיע על אובייקטים או משתנים חיצוניים. זה פותר את הבאג, אבל היית צריך לעשות את הרכיב מחדש בתדירות גבוהה יותר לפני שהתברר שמשהו לא בסדר בהתנהגות שלו.

בדוגמה המקורית, הבאג לא היה ברור. עכשיו בואו נעטוף את הקוד המקורי (באגי) ב-<StrictMode>:

export default function StoryTray({ stories }) {
  const items = stories;
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul>
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

מצב קפדני תמיד קורא לפונקציית העיבוד שלך פעמיים, כך שתוכל לראות את הטעות מיד (“צור סיפור” מופיע פעמיים). זה מאפשר לך להבחין בטעויות כאלה בשלב מוקדם של התהליך. כאשר אתה מתקן את הרכיב שלך לרינדור במצב קפדני, אתה גם מתקן באגים אפשריים בעתיד בייצור כמו פונקציונליות הריחוף מלפני כן:

import { useState } from 'react';

export default function StoryTray({ stories }) {
  const [isHover, setIsHover] = useState(false);
  const items = stories.slice(); // Clone the array
  items.push({ id: 'create', label: 'Create Story' });
  return (
    <ul
      onPointerEnter={() => setIsHover(true)}
      onPointerLeave={() => setIsHover(false)}
      style={{
        backgroundColor: isHover ? '#ddd' : '#fff'
      }}
    >
      {items.map(story => (
        <li key={story.id}>
          {story.label}
        </li>
      ))}
    </ul>
  );
}

ללא מצב קפדני, קל היה לפספס את הבאג עד שהוספת עוד עיבודים מחדש. מצב קפדני גרם לאותו באג להופיע מיד. מצב קפדני עוזר לך למצוא באגים לפני שאתה דוחף אותם לצוות שלך ול-users שלך.

קרא עוד על שמירה על ניקיון רכיבים.

Note

אם מותקן אצלך React DevTools, כל קריאות console.log במהלך קריאת העיבוד השנייה יופיעו מעומעמות מעט. React DevTools מציע גם הגדרה (כבוי כברירת מחדל) כדי לדכא אותם לחלוטין.


תיקון באגים שנמצאו על ידי הפעלה מחדש של אפקטים בפיתוח

מצב קפדני יכול גם לעזור למצוא באגים ב-אפקטים.

לכל אפקט יש קוד הגדרה ויכול להיות שיש לו קוד ניקוי כלשהו. בדרך כלל, React קורא להגדרה כאשר הרכיב מועלה (נוסף למסך) וקורא לניקוי כאשר הרכיב מתבטל (מוסר מהמסך). React אז קורא לניקוי והתקנה שוב אם התלות שלו השתנתה מאז העיבוד האחרון.

כאשר מצב קפדני מופעל, React יפעיל גם מחזור הגדרה+ניקוי נוסף בפיתוח עבור כל אפקט. זה עשוי להרגיש מפתיע, אבל זה עוזר לחשוף באגים עדינים שקשה לתפוס ידנית.

הנה דוגמה כדי להמחיש כיצד הפעלה מחדש של אפקטים במצב קפדני עוזרת לך למצוא באגים מוקדם.

שקול את הדוגמה הזו שמחברת רכיב לצ’אט:

import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);

יש בעיה עם הקוד הזה, אבל ייתכן שהיא לא ברורה מיד.

כדי להפוך את הבעיה לברורה יותר, בואו ליישם תכונה. בדוגמה למטה, roomId אינו מקודד. במקום זאת, ה-user יכול לבחור את ה-roomId שאליו הם רוצים להתחבר מתוך תפריט נפתח. לחץ על “פתח צ’אט” ולאחר מכן בחר חדרי צ’אט שונים אחד אחד. עקוב אחר מספר החיבורים הפעילים במסוף:

import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(<App />);

תבחין שמספר החיבורים הפתוחים תמיד ממשיך לגדול. באפליקציה אמיתית, זה עלול לגרום לבעיות ביצועים ורשת. הבעיה היא שלאפקט שלך חסרה פונקציית ניקוי:

useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);

עכשיו כשהאפקט שלך “מנקה” אחרי עצמו והורס את החיבורים המיושנים, הדליפה נפתרה. עם זאת, שים לב שהבעיה לא נראתה עד שהוספת תכונות נוספות (תיבת הבחירה).

בדוגמה המקורית, הבאג לא היה ברור. עכשיו בואו נעטוף את הקוד המקורי (באגי) ב-<StrictMode>:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

עם Strict Mode רואים מיד שיש בעיה (מספר החיבורים הפעילים קופץ ל-2). מצב קפדני מפעיל מחזור הגדרה+ניקוי נוסף עבור כל אפקט. לאפקט הזה אין הגיון ניקוי, אז הוא יוצר חיבור נוסף אבל לא הורס אותו. זהו רמז לכך שחסרה לך פונקציית ניקוי.

מצב קפדני מאפשר לך להבחין בטעויות כאלה בשלב מוקדם של התהליך. כאשר אתה מתקן את האפקט שלך על ידי הוספת פונקציית ניקוי במצב קפדני, אתה גם מתקן הרבה באגי ייצור עתידיים אפשריים כמו תיבת הבחירה מקודם:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

import App from './App';

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

שימו לב איך ספירת החיבורים הפעילים בקונסולה לא ממשיכה לגדול יותר.

ללא מצב קפדני, קל היה לפספס שהאפקט שלך זקוק לניקוי. על ידי הפעלת setup → cleanup → setup במקום setup עבור האפקט שלך בפיתוח, מצב קפדני הפך את היגיון הניקוי החסר ליותר בולט.

קרא עוד על יישום אפקט ניקוי.


תיקון אזהרות הוצאה משימוש מופעל על ידי מצב קפדני

React מזהיר אם רכיב כלשהו בתוך עץ <StrictMode> uses אחד מה-APIs שהוצא משימוש:

APIs אלה הם בעיקר used ב[רכיבי מחלקה] ישנים יותר (/reference/react/Component) ולכן הם מופיעים רק לעתים רחוקות באפליקציות מודרניות.