برنامه نویسی

فراخوانی بد setState() و راه حل ممکن هنگام رندر!

هشدار: نمی توان یک مؤلفه را به روز کرد (Bookings) در حین رندر کردن کامپوننت متفاوت (BookingConfirmationModal). برای یافتن محل نامناسب setState() در داخل فراخوانی کنید BookingConfirmationModal، ردیابی پشته را همانطور که توضیح داده شد دنبال کنید!

در برنامه های React اغلب با این خطای وحشتناک مواجه می شوید. این خطا زمانی رخ می دهد که شما سعی می کنید وضعیت یک مؤلفه (Bookings) را که عمدتاً مؤلفه والد است، تغییر دهید، در حالی که در حال رندر کردن مؤلفه دیگری (BookingConfirmationModal) است که مؤلفه فرزند است و احتمالاً یک تابع setState() را به آن منتقل کرده اید. آن را به عنوان یک تکیه گاه با این حال، این می تواند منجر به رفتار غیرمنتظره و ناسازگاری در رابط کاربری برنامه شما شود.

در این وبلاگ سعی می کنم شما را از طریق درک این خطا، اشکال زدایی منبع آن و پیاده سازی راه حل های موثر برای جلوگیری از تکرار آن در پروژه های React شما راهنمایی کنم.

درک خطا

فرآیند رندر React به گونه ای طراحی شده است که کارآمد و قابل پیش بینی باشد. هنگامی که وضعیت یا props یک جزء تغییر می کند، React یک فرآیند رندر مجدد را آغاز می کند. در طول این فرآیند، React درخت کامپوننت را طی می‌کند و در صورت نیاز، مؤلفه‌ها را به‌روزرسانی می‌کند و مجدداً رندر می‌کند. مشکل اصلی خطای «نمی‌توان وضعیت به‌روزرسانی در حین رندر» را نقض کرد، این ترتیب رندر قابل پیش‌بینی است. هنگامی که یک کامپوننت سعی می کند وضعیت یک جزء دیگر را در مرحله رندر خود تغییر دهد، چرخه رندر را مختل می کند و می تواند منجر به موارد زیر شود:

  • Infinite Loops: به‌روزرسانی‌های حالت باعث ایجاد رندرهای مجدد مداوم می‌شوند که احتمالاً برنامه را خراب می‌کند.
  • Inconsistent UI: UI ممکن است تغییرات حالت مورد نظر را به درستی منعکس نکند.
  • Data Races: ممکن است چندین مؤلفه سعی کنند به طور همزمان یک حالت را تغییر دهند که منجر به نتایج غیرقابل پیش بینی شود.

علل احتمالی

  • State Update in Render Phase: محتمل ترین علت این است که شما در حال فراخوانی setState در داخل متد رندر یا در طول فرآیند رندر BookingConfirmationModal هستید.

  • Side Effects in Render: ممکن است مستقیماً در روش رندر عوارض جانبی (مانند واکشی داده یا به‌روزرسانی وضعیت) داشته باشید که باید از آن اجتناب شود.

راه حل

برای رفع این مشکل، باید مطمئن شوید که به‌روزرسانی‌های حالت در مرحله رندر انجام نمی‌شود! در اینجا چند مرحله وجود دارد که می توانید انجام دهید:

  • Move State Updates to useEffect: اگر می‌خواهید وضعیت را بر اساس شرایطی به‌روزرسانی کنید، از هوک useEffect برای انجام به‌روزرسانی پس از رندر شدن مؤلفه استفاده کنید.
import React, { useEffect } from 'react';

const BookingConfirmationModal = ({ someProp }) => {
  useEffect(() => {
    // Perform state updates here
    // Example: setState(someValue);
  }, [someProp]); // Add dependencies if needed

  return (
    <div>
      {/* Your component JSX */}
    </div>
  );
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  • Avoid Direct State Updates in Render: مطمئن شوید که setState را مستقیماً در متد رندر یا هر تابعی که در حین رندر فراخوانی می شود، فراخوانی نمی کنید.

  • Check for Conditional State Updates: اگر منطق شرطی دارید که حالت را به روز می کند، مطمئن شوید که در مرحله رندر اجرا نمی شود.

  • Check your useMemo: اگر استفاده کرده اید در یادداشت پوشاندن، آن را بردارید و استفاده کنید useEffect به جای آن در کامپوننت فرزند به طوری که پس از سوار شدن کامپوننت یا حرکت شما اجرا شود در یادداشت به جزء والد این اخطار را حل می کند.

یک راه حل ممکن به نظر می رسد –


import { useState, useEffect } from "react";
import BookingConfirmationModal from "./BookingConfirmationModal";

function App() {
  const [showModal, setShowModal] = useState(false);
  // other code

  return (
    <div>
      <h1>This is app</h1>
      <button onClick={() => setShowModal(true)}>Show Modal</button>
      {showModal ? <Testing BookingConfirmationModal={setTestingState} /> : null}
    </div>
  );
}

export default App;

// BookingConfirmationModal.jsx
const BookingConfirmationModal= ({ setTestingState }) => {

  useEffect(()=> {
    setTestingState(false)
   }, [setIsModalVisible]) //or other required dependencies

  return (
    <div>
      <button onClick={() => setTestingState(false)}>Close Modal</button>
      // other codes
    </div>
  );
};

export default BookingConfirmationModal;
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کد نویسی مبارک!

می خواهم پیشنهاداتی ارائه دهم: –

من را در لینکدین توییتر پیدا کنید

به من ایمیل بزنید labib.ahmed.372@gmail.com

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا