برنامه نویسی

15 مورد برتر در مورد اشتباهات استفاده مجدد هر برنامه نویس باید بدانند

هوک Usestate یکی از متداول ترین قلاب در React است ، اما چند اشتباه ظریف وجود دارد که توسعه دهندگان اغلب مرتکب می شوند.

در این مقاله ، شما یاد خواهید گرفت که چگونه از آنها جلوگیری کنید و منطق حالت بهتری بنویسید.


فهرست مطالب

اشتباه 1: فرض کنید که به روزرسانی های SetState بلافاصله وضعیت

عملکرد SetState React ناهمزمان است ، به این معنی که دولت بلافاصله به روز نمی شود. اگر سعی می کنید بلافاصله پس از تماس با SetState از حالت به روز شده استفاده کنید ، باز هم مقدار قدیمی را دریافت خواهید کرد.

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

function increment() {
  setCount(count + 1);
  setCount(count + 1); // count is still 0 and not incremented to 1
}
حالت تمام صفحه را وارد کنید

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

راه حل: از فرم به روزرسانی عملکردی استفاده کنید

وقتی حالت جدید به حالت قبلی بستگی دارد ، از فرم عملکردی استفاده کنید setStateبشر

function increment() {
  setCount(prevCount => prevCount + 1);   
  setCount(prevCount => prevCount + 1); // Always works reliably
}
حالت تمام صفحه را وارد کنید

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


اشتباه 2: استفاده از اشیاء بدون حالت ادغام

هنگام کار با اشیاء در useState، React به طور خودکار حالت جدید را با حالت قدیمی مانند ادغام نمی کند this.setState در اجزای کلاس انجام می شود. در مؤلفه های کاربردی ، شما باید به صورت دستی شی را ادغام کنید.

const [user, setUser] = useState({ name: 'John', age: 30 });

function updateAge() {
  setUser({ age: 31 }); // Overwrites the entire user state, removing `name`
}
حالت تمام صفحه را وارد کنید

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

راه حل: حالت قبلی را پخش کنید

همیشه حالت قبلی را برای حفظ خواص موجود گسترش دهید.

function updateAge() {
  setUser(prevUser => ({ ...prevUser, age: 31 })); // Keeps `name` intact
}
حالت تمام صفحه را وارد کنید

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


اشتباه 3: با استفاده از حالت بی نظیر در دستگیرندگان رویداد

اگر کنترل کننده رویداد شما به وضعیت فعلی (به عنوان مثال ، داخل یک حلقه یا عملکرد Async) متکی است ، ممکن است به طور تصادفی از مقادیر حالت بی نظیر استفاده کنید.

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

function handleClick() {
  setTimeout(() => {
    setCount(count + 1); // Uses the stale `count` value
  }, 1000);
}
حالت تمام صفحه را وارد کنید

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

راه حل: از فرم به روزرسانی عملکردی استفاده کنید

برای اطمینان از اینکه همیشه آخرین حالت را دارید ، از فرم به روزرسانی عملکردی استفاده کنید.

function handleClick() {
  setTimeout(() => {
    setCount(prevCount => prevCount + 1); // Always gets the latest value
  }, 1000);
}
حالت تمام صفحه را وارد کنید

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


اشتباه 4: استفاده از حالت مشتق شده در مؤلفه

به جای ذخیره مقادیر مشتق شده (مانند خواص محاسبه شده) در حالت ، آنها را در پرواز محاسبه کنید. این باعث می شود مجدداً غیر ضروری کاهش یابد و منطق حالت شما را ساده نگه می دارد.

const [firstName, setFirstName] = useState('John');
const [lastName, setLastName] = useState('Doe');
const [fullName, setFullName] = useState(`${firstName} ${lastName}`); // Derived state

function updateFirstName(name) {
  setFirstName(name);
  setFullName(`${name} ${lastName}`); // Extra work to keep `fullName` in sync
}
حالت تمام صفحه را وارد کنید

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

راه حل: مقادیر مشتق شده را مستقیماً محاسبه کنید

const [firstName, setFirstName] = useState('John');
const [lastName, setLastName] = useState('Doe');

// Calculate fullName dynamically
const fullName = `${firstName} ${lastName}`;
حالت تمام صفحه را وارد کنید

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


اشتباه 5: عدم استفاده از اولیه سازی تنبل برای محاسبات گران قیمت دولت

اگر حالت اولیه شما شامل یک محاسبات گران است (به عنوان مثال ، واکشی داده ها ، تجزیه JSON یا مقادیر محاسبه) ، می توانید از یک استفاده کنید عمل برای اولیه کردن دولت با تنبلی. این تضمین می کند که محاسبه فقط یک بار اتفاق می افتد و عملکرد را بهبود می بخشد.

const [data, setData] = useState(expensiveComputation()); // Runs every re-render of component
حالت تمام صفحه را وارد کنید

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

راه حل: از اولیه سازی تنبل استفاده کنید

const [data, setData] = useState(() => expensiveComputation()); // Runs only once first time component is rendered
حالت تمام صفحه را وارد کنید

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

این امر به ویژه در هنگام برخورد با مجموعه داده های بزرگ یا منطق پیچیده در هنگام اولیه سازی مفید است.


اشتباه 6: تنظیم مجدد دستی هر ایالت برای تنظیم مجدد کامل

هنگام جابجایی بین مؤلفه ها یا فرم های تنظیم مجدد ، ممکن است بخواهید حالت را به مقدار اولیه آن تنظیم کنید.

به جای تنظیم مجدد دستی هر قطعه از حالت ، می توانید از یک پیشخدمت کلیدی برای مجبور کردن واکنش به نابودی و بازپرداخت مؤلفه.

const [inputValue, setInputValue] = useState('');

function resetForm() {
  setInputValue(''); // Manually reset each piece of state
}
حالت تمام صفحه را وارد کنید

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

راه حل: تنظیم مجدد خودکار با key

با تغییر key Prop ، React مؤلفه را از بین می برد و مجدداً مجدداً تنظیم می کند و به طور خودکار تمام حالت را دوباره تنظیم می کند.

هر وقت مقدار متفاوتی را برای آن عبور می دهید key برای یک مؤلفه ، مؤلفه دوباره ایجاد می شود.

function App() {
  const [formKey, setFormKey] = useState(0);

  function resetForm() {
    setFormKey(prevKey => prevKey + 1); // Forces a reset
  }

  return (
    <div>
      <MyForm key={formKey} />
      <button onClick={resetForm}>Reset Form</button>
    </div>
  );
}
حالت تمام صفحه را وارد کنید

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


اشتباه 7: عدم استفاده از آرایه ها یا اشیاء برای حالت مرتبط

به جای ایجاد چندین useState قلاب برای قطعات مربوط به حالت ، آنها را به یک شیء یا آرایه واحد گروه بندی کنید. این باعث می شود کد شما سازمان یافته تر و مدیریت آن آسان تر شود.

const [x, setX] = useState(0);
const [y, setY] = useState(0);

function updateCoordinates(newX, newY) {
  setX(newX);
  setY(newY);
}
حالت تمام صفحه را وارد کنید

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

راه حل: با استفاده از حالت ترکیبی

const [coordinates, setCoordinates] = useState({ x: 0, y: 0 });

function updateCoordinates(newX, newY) {
  setCoordinates({ x: newX, y: newY });
}
حالت تمام صفحه را وارد کنید

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

اشتباه 8: عدم استفاده از قلاب کاربر برای منطق پیچیده

برای انتقال حالت پیچیده (به عنوان مثال ، چندین حالت مرتبط یا به روزرسانی های مشروط) ، ترکیب را در نظر بگیرید useState با useReducerبشر این رویکرد ترکیبی کد شما را مدولار و قابل خواندن نگه می دارد.

const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);

async function fetchData() {
  setLoading(true);
  try {
    const response = await fetch('https://api.example.com/data');
    const result = await response.json();
    setData(result);
  } catch (err) {
    setError(err.message);
  } finally {
    setLoading(false);
  }
}
حالت تمام صفحه را وارد کنید

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

راه حل: استفاده کنید useReducer برای حالت پیچیده

const initialState = { loading: false, error: null, data: null };

function reducer(state, action) {
  switch (action.type) {
    case 'FETCH_START':
      return { ...state, loading: true, error: null };
    case 'FETCH_SUCCESS':
      return { ...state, loading: false, data: action.payload };
    case 'FETCH_ERROR':
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
}

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);

  async function fetchData() {
    dispatch({ type: 'FETCH_START' });
    try {
      const response = await fetch('https://api.example.com/data');
      const result = await response.json();
      dispatch({ type: 'FETCH_SUCCESS', payload: result });
    } catch (err) {
      dispatch({ type: 'FETCH_ERROR', payload: err.message });
    }
  }

  return (
    <div>
      {state.loading && <p>Loading...</p>}
      {state.error && <p>Error: {state.error}</p>}
      {state.data && <pre>{JSON.stringify(state.data, null, 2)}</pre>}
    </div>
  );
}
حالت تمام صفحه را وارد کنید

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

این رویکرد منطق دولت را متمرکز می کند و مدیریت انتقال پیچیده را آسان تر می کند.


اشتباه 9: عدم استفاده از قلاب سفارشی برای تعامل با داده های محلی

با همگام سازی آن با ذخیره محلی ، حالت بارگذاری مجدد در صفحه را ادامه دهید. استفاده کردن useState در ترکیب با useEffect برای دستیابی به این یکپارچه در قلاب سفارشی.

const [theme, setTheme] = useState('light');

function toggleTheme() {
  const newTheme = theme === 'light' ? 'dark' : 'light';
  setTheme(newTheme);
  localStorage.setItem('theme', newTheme);
}
حالت تمام صفحه را وارد کنید

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

راه حل: همگام سازی ذخیره سازی محلی

حالت همگام سازی را با ذخیره محلی همگام سازی کنید.

const useLocalStorage = (key, initialValue) => {
  const [value, setValue] = useState(() => {
    try {
      const localValue = window.localStorage.getItem(key);
      return localValue ? JSON.parse(localValue) : initialValue;
    } catch (error) {
      return initialValue;
    }
  });

  useEffect(() => {
    window.localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
};

function App() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');

  function toggleTheme() {
    setTheme(theme === 'light' ? 'dark' : 'light');
  }

  return (
    <div>
      <p>Current Theme: {theme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
}
حالت تمام صفحه را وارد کنید

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

این رویکرد تضمین می کند که دولت شما بدون مداخله دستی در جلسات ادامه می یابد.

یاد بگیرید که با استفاده از این رویکرد برنامه مدیریت کتاب را بسازید


اشتباه 10: بازنویسی داده های حالت با استفاده از ورودی های کنترل شده

هنگام مدیریت ورودی های کنترل شده (به عنوان مثال ، فرم ها) ، با استفاده از صحیح استفاده از ورودی کاربر خودداری کنید onChange رویداد

const [formData, setFormData] = useState({ name: '', email: '' });

function handleChange(event) {
  setFormData({ [event.target.name]: event.target.value }); // Overwrites other fields
}
حالت تمام صفحه را وارد کنید

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

همیشه مقادیر موجود را برای حفظ زمینه های دیگر پخش کنید.

راه حل: مقادیر موجود را پخش کنید

function handleChange(event) {
  const { name, value } = event.target;
  setFormData(prevData => ({ ...prevData, [name]: value })); // Preserves other fields
}
حالت تمام صفحه را وارد کنید

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

این تضمین می کند که تمام زمینه های موجود در فرم در حالی که فقط مورد مربوطه را به روز می کنند ، دست نخورده باقی می مانند.


اشتباه 11: عدم انجام چک های برابری در هنگام بروزرسانی دولت

React به طور خودکار بررسی نمی کند که آیا حالت جدید قبل از ایجاد یک رندر دوباره با حالت قدیمی متفاوت است یا خیر. برای جلوگیری از به روزرسانی های غیر ضروری ، به طور دستی مقدار جدید را با وضعیت فعلی مقایسه کنید.

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

function updateCount(newCount) {
  setCount(newCount); // Triggers a re-render even if `newCount === count`
}
حالت تمام صفحه را وارد کنید

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

راه حل: یک بررسی برابری اضافه کنید

function updateCount(newCount) {
  if (newCount !== count) {
    setCount(newCount); // Only updates state if the value changes
  }
}
حالت تمام صفحه را وارد کنید

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

این امر مانع از تولید مجدد مجدد و بهبود عملکرد می شود.


اشتباه 12: همیشه از Redux یا زمینه برای ذخیره داده ها استفاده کنید

برای حالت های UI موقت (به عنوان مثال ، نشان دادن/پنهان کردن ماژال ها ، کشویی در حال جابجایی) ، استفاده کنید useState به جای مدیریت این حالتها در سطح جهان (به عنوان مثال ، در ردوکس یا متن). این باعث می شود حالت جهانی شما تمیز و متمرکز بر داده های گسترده برنامه باشد.

// Storing modal visibility in Redux or Context is Not good
dispatch({ type: 'SET_MODAL_VISIBLE', payload: true });
حالت تمام صفحه را وارد کنید

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

راه حل: از دولت محلی استفاده کنید

const [isModalOpen, setIsModalOpen] = useState(false);

function openModal() {
  setIsModalOpen(true);
}

function closeModal() {
  setIsModalOpen(false);
}

return (
  <div>
    <button onClick={openModal}>Open Modal</button>
    {isModalOpen && <Modal onClose={closeModal} />}
  </div>
);
حالت تمام صفحه را وارد کنید

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


اشتباه 13: عدم استفاده از نحو عملکرد Updater برای عملیات Async

هنگام به روزرسانی حالت بر اساس عملیات ناهمزمان (به عنوان مثال ، واکشی داده ها) ، همیشه از به روزرسانی های عملکردی استفاده کنید تا اطمینان حاصل کنید که با آخرین حالت کار می کنید.

const [data, setData] = useState([]);

async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  const newData = await response.json();
  setData([...data, ...newData]); // Uses stale `data`
}
حالت تمام صفحه را وارد کنید

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

راه حل: از نحو به روزرسانی عملکردی استفاده کنید

async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  const newData = await response.json();
  setData(prevData => [...prevData, ...newData]); // Always uses the latest state
}
حالت تمام صفحه را وارد کنید

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


اشتباه 14: استفاده نکردن useState برای ارائه مشروط با ماشین های دولتی

برای جریان های پیچیده UI (به عنوان مثال ، فرم های چند مرحله ای ، جادوگران) ، استفاده کنید useState برای اجرای یک دستگاه دولتی ساده. این باعث می شود منطق شما سازمان یافته و قابل پیش بینی باشد.

const [step, setStep] = useState(1);

return (
  <div>
    {step === 1 && <Step1 />}
    {step === 2 && <Step2 />}
    {step === 3 && <Step3 />}
  </div>
);
حالت تمام صفحه را وارد کنید

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

راه حل: از یک دستگاه دولتی استفاده کنید

با استفاده از دستگاه حالت ، هر مرحله را به یک جزء نقشه برداری کنید.

const steps = [<Step1 />, <Step2 />, <Step3 />];
const [currentStep, setCurrentStep] = useState(0);

function nextStep() {
  setCurrentStep(prevStep => Math.min(prevStep + 1, steps.length - 1));
}

function prevStep() {
  setCurrentStep(prevStep => Math.max(prevStep - 1, 0));
}

return (
  <div>
    {steps[currentStep]}
    <button onClick={prevStep} disabled={currentStep === 0}>
      Previous
    </button>
    <button onClick={nextStep} disabled={currentStep === steps.length - 1}>
      Next
    </button>
  </div>
);
حالت تمام صفحه را وارد کنید

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


اشتباه 15: به روزرسانی دستی خصوصیات تو در تو

هنگام مدیریت حالت پیچیده تو در تو (به عنوان مثال ، اشیاء یا آرایه های عمیقاً تو در تو) ، از یاران ناپذیری مانند استفاده کنید immer برای ساده تر کردن به روزرسانی ها در حالی که حالت خود را تغییر ناپذیر می کند.

const [user, setUser] = useState({ name: 'John', address: { city: 'New York' } });

function updateCity(newCity) {
  setUser(prevUser => ({
    ...prevUser,
    address: { ...prevUser.address, city: newCity }, // Tedious and error-prone
  }));
}
حالت تمام صفحه را وارد کنید

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

راه حل: برای سادگی از Immer استفاده کنید

نصب کردن immer کتابخانه (npm install immer) و به روزرسانی های تو در تو را ساده کنید.

import produce from 'immer';

const [user, setUser] = useState({ name: 'John', address: { city: 'New York' } });

function updateCity(newCity) {
  setUser(
    produce(draft => {
      draft.address.city = newCity; // Mutate draft immutably
    })
  );
}
حالت تمام صفحه را وارد کنید

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

با من ارتباط برقرار کنید

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

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

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

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