Kodax

React.memo و Optimization — مقدمة React

تحسين الأداء في React

React.memo

// المكون يُعاد render فقط عند تغير props
const ExpensiveComponent = React.memo(function ExpensiveComponent({ data }) {
  // حسابات مكلفة...
  return <div>{data}</div>;
});

// مع دالة مقارنة مخصصة
const MemoizedList = React.memo(
  function List({ items }) {
    return (
      <ul>
        {items.map(item => <li key={item.id}>{item.name}</li>)}
      </ul>
    );
  },
  (prevProps, nextProps) => {
    // return true إذا لا نريد إعادة render
    return prevProps.items.length === nextProps.items.length;
  }
);

useCallback

function ParentComponent() {
  const [count, setCount] = useState(0);
  
  // بدون useCallback، handleClick جديدة في كل render
  const handleClick = useCallback(() => {
    console.log('Clicked!');
  }, []); // لا يوجد dependencies

  const handleCountClick = useCallback(() => {
    setCount(c => c + 1);
  }, []); // الدالة مستقرة

  return (
    <div>
      <ChildComponent onClick={handleClick} />
      <AnotherChild onIncrement={handleCountClick} />
    </div>
  );
}

useMemo

function DataTable({ items, filter }) {
  // حساب مكلف يُنفذ فقط عند تغير items أو filter
  const filteredItems = useMemo(() => {
    console.log('Filtering...');
    return items.filter(item => 
      item.name.toLowerCase().includes(filter.toLowerCase())
    );
  }, [items, filter]);

  return (
    <table>
      <tbody>
        {filteredItems.map(item => (
          <tr key={item.id}>
            <td>{item.name}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}
// مثال شامل على التحسين
const SearchableList = React.memo(function SearchableList({ items }) {
  const [search, setSearch] = useState('');
  
  // تصفية مُحسّنة
  const filteredItems = useMemo(() => {
    return items.filter(item => 
      item.name.toLowerCase().includes(search.toLowerCase())
    );
  }, [items, search]);
  
  // handler مستقر
  const handleSearch = useCallback((e) => {
    setSearch(e.target.value);
  }, []);
  
  return (
    <div>
      <input 
        value={search} 
        onChange={handleSearch} 
        placeholder="ابحث..."
      />
      <ul>
        {filteredItems.map(item => (
          <ListItem key={item.id} item={item} />
        ))}
      </ul>
    </div>
  );
});

// مكون فرعي محسّن
const ListItem = React.memo(function ListItem({ item }) {
  return <li>{item.name}</li>;
});
اختبر فهمك