Kodokon kodokon.com

गुणवत्ता: Testing Library, StrictMode, Profiler

implementation के बजाय व्यवहार का परीक्षण करें, StrictMode के दोहरे invocations का लाभ उठाएँ, और Profiler के साथ renders मापें।

10 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

Testing Library का दर्शन एक वाक्य में समा जाता है: उसका परीक्षण करें जो उपयोगकर्ता अनुभव करता है, कभी implementation विवरणों का नहीं। ठोस रूप से, आप DOM को accessibility tree के माध्यम से query करते हैं: पहले getByRole (queries की रानी, जो साथ-साथ आपकी ARIA roles को मान्य करती है), फिर getByLabelText, getByText, और getByTestId केवल अंतिम उपाय के रूप में। अंतःक्रियाओं के लिए, fireEvent के बजाय user-event को प्राथमिकता दें: जहाँ fireEvent.change एक अलग event उत्सर्जित करता है, वहीं user.type पूरा क्रम पुनरुत्पन्न करता है (focus, keydown, keypress, input, keyup), ठीक एक असली keyboard की तरह। findBy* variants एक query को एक async प्रतीक्षा के साथ जोड़ते हैं: किसी loading चरण के बाद आवश्यक।

JSX
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('adds a task to the list', async () => {
  const user = userEvent.setup();
  render(<TodoApp />);

  await user.type(
    screen.getByRole('textbox'),
    'Review the report'
  );
  await user.click(
    screen.getByRole('button', { name: /add/i })
  );

  expect(
    await screen.findByText('Review the report')
  ).toBeInTheDocument();
});
एक परीक्षण जो व्यवहार पर केंद्रित है, implementation पर नहीं।

StrictMode एक development उपकरण है जिसका production में बिल्कुल कोई प्रभाव नहीं होता। development में, यह आपके component functions, state initializers, और setState को पास किए गए functions को दो बार call करता है, अशुद्ध renders को बाहर निकालने के लिए: अगर दो executions अलग परिणाम देते हैं, तो आपके पास एक छिपा हुआ side effect है। React 18 से, यह हर effect को mount, unmount, remount चक्र से भी गुज़ारता है: एक effect जिसकी cleanup पूरी तरह सममित नहीं है (कभी रद्द न की गई subscription, कभी abort न की गई request) तुरंत अपनी पोल खोल देता है। यह उन features की सीधी तैयारी है जहाँ React किसी screen की state को सुरक्षित रखते हुए उसे unmount फिर remount करता है।

JSX
useEffect(() => {
  const controller = new AbortController();
  fetch('/api/user', { signal: controller.signal })
    .then((res) => res.json())
    .then(setUser)
    .catch(() => {});
  return () => controller.abort();
}, []);
एक सममित effect StrictMode के दोहरे mounting से बच जाता है।

मापने के लिए, React <Profiler> component और DevTools में उसका ग्राफ़िकल समकक्ष प्रदान करता है। उसका onRender callback, अन्य बातों के अलावा, phase (mount, update, या nested-update), actualDuration (इस commit के लिए subtree को render करने में वास्तव में लगा समय), और baseDuration (बिना किसी memoization के पूरे subtree को render करने के समय का एक अनुमान) प्राप्त करता है। दोनों के बीच का अंतर आपके memo और useMemo की प्रभावशीलता को मापता है: baseDuration से बहुत कम actualDuration का मतलब है कि memoization आपके लिए काम कर रहा है।

JSX
import { Profiler } from 'react';

function App() {
  return (
    <Profiler
      id="Sidebar"
      onRender={(id, phase, actualDuration) => {
        console.log(id, phase, actualDuration);
      }}
    >
      <Sidebar />
    </Profiler>
  );
}
किसी subtree की वास्तविक render लागत को मापना।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. StrictMode development में हर effect को mount, unmount, फिर remount क्यों करता है?
    • server network latency का अनुकरण करने के लिए
    • यह जाँचने के लिए कि हर effect की cleanup सममित है
    • React के आंतरिक cache को साफ़ करने के लिए
    • update batching को मजबूर करने के लिए
  2. किस Testing Library query को आपको पहले चुनना चाहिए?
    • getByTestId, सबसे स्थिर
    • getByClassName, सबसे सटीक
    • getByRole, accessibility tree के अनुरूप
    • querySelector, सबसे लचीला
  3. Profiler callback में baseDuration क्या दर्शाता है?
    • केवल अंतिम commit का समय
    • बिना किसी memoization के subtree का अनुमानित render समय
    • component के mount होने के बाद से बीता समय
    • अंतिम दस renders की औसत अवधि