Reactããã¯ã®ãã¹ãã«é¢ããå æ¬çãªã¬ã€ããReactã¢ããªã±ãŒã·ã§ã³ã®ä¿¡é Œæ§ã確ä¿ããããã®æ§ã ãªæŠç¥ãããŒã«ããã¹ããã©ã¯ãã£ã¹ã解説ããŸãã
ããã¯ã®ãã¹ãïŒå ç¢ãªã³ã³ããŒãã³ãã®ããã®Reactãã¹ãæŠç¥
Reactããã¯ã¯ã颿°ã³ã³ããŒãã³ããç¶æ ãå¯äœçšã管çã§ããããã«ããã³ã³ããŒãã³ãã®æ§ç¯æ¹æ³ã«é©åœããããããŸããããããããã®æ°ããªåã«ã¯ããããã®ããã¯ã培åºçã«ãã¹ããããŠããããšãä¿èšŒãã責任ã䌎ããŸãããã®å æ¬çãªã¬ã€ãã§ã¯ãReactããã¯ããã¹ãããããã®æ§ã ãªæŠç¥ãããŒã«ããã¹ããã©ã¯ãã£ã¹ãæ¢æ±ããReactã¢ããªã±ãŒã·ã§ã³ã®ä¿¡é Œæ§ãšä¿å®æ§ã確ä¿ããŸãã
ãªãããã¯ããã¹ãããã®ãïŒ
ããã¯ã¯ãè€æ°ã®ã³ã³ããŒãã³ãéã§ç°¡åã«å ±æã§ããåå©çšå¯èœãªããžãã¯ãã«ãã»ã«åããŸããããã¯ããã¹ãããããšã«ã¯ãããã€ãã®éèŠãªå©ç¹ããããŸãïŒ
- åé¢ïŒ ããã¯ãåé¢ããŠãã¹ãã§ãããããåšå²ã®ã³ã³ããŒãã³ãã®è€éããªãã«ãããã¯ã«å«ãŸããç¹å®ã®ããžãã¯ã«éäžã§ããŸãã
- åå©çšæ§ïŒ 培åºçã«ãã¹ããããããã¯ã¯ä¿¡é Œæ§ãé«ããã¢ããªã±ãŒã·ã§ã³ã®ç°ãªãéšåãä»ã®ãããžã§ã¯ãã§ãåå©çšãããããªããŸãã
- ä¿å®æ§ïŒ ãããã¹ããããããã¯ã¯ãããä¿å®ããããã³ãŒãããŒã¹ã«è²¢ç®ããŸããããã¯ã®ããžãã¯ãžã®å€æŽãä»ã®ã³ã³ããŒãã³ãã§äºæãã¬ãã°ãåŒãèµ·ããå¯èœæ§ãäœããªããŸãã
- ä¿¡é Œæ§ïŒ å æ¬çãªãã¹ãã¯ããã¯ã®æ£ããã«å¯Ÿããèªä¿¡ããããããããå ç¢ã§ä¿¡é Œæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ã«ã€ãªãããŸãã
ããã¯ã®ãã¹ãçšããŒã«ãšã©ã€ãã©ãª
Reactããã¯ã®ãã¹ãã«åœ¹ç«ã€ããã€ãã®ããŒã«ãšã©ã€ãã©ãªããããŸãïŒ
- JestïŒ ã¢ããã³ã°ãã¹ãããã·ã§ãããã¹ããã³ãŒãã«ãã¬ããžãªã©ãå æ¬çãªæ©èœã»ãããæäŸãã人æ°ã®JavaScriptãã¹ããã¬ãŒã ã¯ãŒã¯ã§ããJestã¯ãã°ãã°React Testing Libraryãšçµã¿åãããŠäœ¿çšãããŸãã
- React Testing LibraryïŒ ãŠãŒã¶ãŒã®èŠç¹ããã³ã³ããŒãã³ãããã¹ãããããšã«çŠç¹ãåœãŠãã©ã€ãã©ãªã§ããŠãŒã¶ãŒãã³ã³ããŒãã³ããšå¯Ÿè©±ããã®ãšåãæ¹æ³ã§ãã¹ããæžãããšã奚å±ããŸããReact Testing Libraryã¯ããã¯ãšããŸã飿ºããããã¯ã䜿çšããã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ãæäœã®ããã®ãŠãŒãã£ãªãã£ãæäŸããŸãã
- @testing-library/react-hooksïŒ ïŒçŸåšã¯éæšå¥šãšãªããæ©èœã¯React Testing Libraryã«çµ±åãããŠããŸãïŒããã¯ããã¯ãåé¢ããŠãã¹ãããããã®å°çšã©ã€ãã©ãªã§ãããéæšå¥šã§ããããã®ååã¯ä»ã§ãæå¹ã§ããããã¯ãåŒã³åºãã«ã¹ã¿ã ãã¹ãã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããpropsã®æŽæ°ãç¶æ ã®æŽæ°ãåŸ ã€ããã®ãŠãŒãã£ãªãã£ãæäŸããŠããŸããããã®æ©èœã¯React Testing Libraryã«ç§»è¡ãããŸããã
- EnzymeïŒ ïŒçŸåšã¯ããŸãäžè¬çã§ã¯ãããŸããïŒåã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããã«ã³ã³ããŒãã³ããåé¢ããŠãã¹ãã§ãããã·ã£ããŒã¬ã³ããªã³ã°APIãæäŸããå€ããã¹ãã©ã€ãã©ãªã§ããäžéšã®ãããžã§ã¯ãã§ã¯ãŸã 䜿çšãããŠããŸããããŠãŒã¶ãŒäžå¿ã®ãã¹ãã«çŠç¹ãåœãŠãŠãããããäžè¬çã«ã¯React Testing Libraryã奜ãŸããŸãã
æ§ã ãªçš®é¡ã®ããã¯ã«å¯Ÿãããã¹ãæŠç¥
æ¡çšããå ·äœçãªãã¹ãæŠç¥ã¯ããã¹ãããããã¯ã®çš®é¡ã«ãã£ãŠç°ãªããŸãã以äžã¯ãäžè¬çãªã·ããªãªãšæšå¥šãããã¢ãããŒãã§ãïŒ
1. åçŽãªç¶æ ããã¯ïŒuseStateïŒã®ãã¹ã
ç¶æ ããã¯ã¯ãã³ã³ããŒãã³ãå ã®åçŽãªç¶æ ã管çããŸãããããã®ããã¯ããã¹ãããã«ã¯ãReact Testing Libraryã䜿çšããŠããã¯ã䜿çšããã³ã³ããŒãã³ããã¬ã³ããªã³ã°ãããã®ã³ã³ããŒãã³ããšå¯Ÿè©±ããŠç¶æ ã®æŽæ°ãããªã¬ãŒããŸããç¶æ ãæåŸ ã©ããã«æŽæ°ãããããšãã¢ãµãŒãããŸãã
äŸïŒ
```javascript // CounterHook.js import { useState } from 'react'; const useCounter = (initialValue = 0) => { const [count, setCount] = useState(initialValue); const increment = () => { setCount(count + 1); }; const decrement = () => { setCount(count - 1); }; return { count, increment, decrement }; }; export default useCounter; ``` ```javascript // CounterHook.test.js import { render, screen, fireEvent } from '@testing-library/react'; import useCounter from './CounterHook'; function CounterComponent() { const { count, increment, decrement } = useCounter(0); return (Count: {count}
2. å¯äœçšãæã€ããã¯ïŒuseEffectïŒã®ãã¹ã
ãšãã§ã¯ãããã¯ã¯ãããŒã¿ã®ãã§ãããã€ãã³ãã®è³Œèªãªã©ã®å¯äœçšãå®è¡ããŸãããããã®ããã¯ããã¹ãããã«ã¯ãå€éšã®äŸåé¢ä¿ãã¢ãã¯ããããéåæãã¹ãæè¡ã䜿çšããŠå¯äœçšãå®äºããã®ãåŸ ã€å¿ èŠãããå ŽåããããŸãã
äŸïŒ
```javascript // DataFetchingHook.js import { useState, useEffect } from 'react'; const useDataFetching = (url) => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const json = await response.json(); setData(json); } catch (error) { setError(error); } finally { setLoading(false); } }; fetchData(); }, [url]); return { data, loading, error }; }; export default useDataFetching; ``` ```javascript // DataFetchingHook.test.js import { renderHook, waitFor } from '@testing-library/react'; import useDataFetching from './DataFetchingHook'; global.fetch = jest.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ name: 'Test Data' }), }) ); test('fetches data successfully', async () => { const { result } = renderHook(() => useDataFetching('https://example.com/api')); await waitFor(() => expect(result.current.loading).toBe(false)); expect(result.current.data).toEqual({ name: 'Test Data' }); expect(result.current.error).toBe(null); }); test('handles fetch error', async () => { global.fetch = jest.fn(() => Promise.resolve({ ok: false, status: 404, }) ); const { result } = renderHook(() => useDataFetching('https://example.com/api')); await waitFor(() => expect(result.current.loading).toBe(false)); expect(result.current.error).toBeInstanceOf(Error); }); ```æ³šïŒ `renderHook` ã¡ãœããã䜿çšãããšãããã¯ãã³ã³ããŒãã³ãã§ã©ããããããšãªããç¬ç«ããŠã¬ã³ããªã³ã°ã§ããŸãã`waitFor` 㯠`useEffect` ããã¯ã®éåææ§ãåŠçããããã«äœ¿çšãããŸãã
3. ã³ã³ããã¹ãããã¯ïŒuseContextïŒã®ãã¹ã
ã³ã³ããã¹ãããã¯ã¯ãReactã³ã³ããã¹ãããå€ãåãåããŸãããããã®ããã¯ããã¹ãããã«ã¯ããã¹ãäžã«ã¢ãã¯ã®ã³ã³ããã¹ãå€ãæäŸããå¿ èŠããããŸããããã¯ããã¹ãå ã§ããã¯ã䜿çšããã³ã³ããŒãã³ããContext Providerã§ã©ããããããšã§å®çŸã§ããŸãã
äŸïŒ
```javascript // ThemeContext.js import React, { createContext, useState } from 'react'; export const ThemeContext = createContext(); export const ThemeProvider = ({ children }) => { const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme(theme === 'light' ? 'dark' : 'light'); }; return (Theme: {theme}
4. ãªãã¥ãŒãµãŒããã¯ïŒuseReducerïŒã®ãã¹ã
ãªãã¥ãŒãµãŒããã¯ã¯ããªãã¥ãŒãµãŒé¢æ°ã䜿çšããŠè€éãªç¶æ æŽæ°ã管çããŸãããããã®ããã¯ããã¹ãããã«ã¯ããªãã¥ãŒãµãŒã«ã¢ã¯ã·ã§ã³ããã£ã¹ãããããç¶æ ãæ£ããæŽæ°ãããããšãã¢ãµãŒãããŸãã
äŸïŒ
```javascript // CounterReducerHook.js import { useReducer } from 'react'; const reducer = (state, action) => { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: return state; } }; const useCounterReducer = (initialValue = 0) => { const [state, dispatch] = useReducer(reducer, { count: initialValue }); const increment = () => { dispatch({ type: 'increment' }); }; const decrement = () => { dispatch({ type: 'decrement' }); }; return { count: state.count, increment, decrement, dispatch }; //Expose dispatch for testing }; export default useCounterReducer; ``` ```javascript // CounterReducerHook.test.js import { renderHook, act } from '@testing-library/react'; import useCounterReducer from './CounterReducerHook'; test('increments the counter using dispatch', () => { const { result } = renderHook(() => useCounterReducer(0)); act(() => { result.current.dispatch({type: 'increment'}); }); expect(result.current.count).toBe(1); }); test('decrements the counter using dispatch', () => { const { result } = renderHook(() => useCounterReducer(0)); act(() => { result.current.dispatch({ type: 'decrement' }); }); expect(result.current.count).toBe(-1); }); test('increments the counter using increment function', () => { const { result } = renderHook(() => useCounterReducer(0)); act(() => { result.current.increment(); }); expect(result.current.count).toBe(1); }); test('decrements the counter using decrement function', () => { const { result } = renderHook(() => useCounterReducer(0)); act(() => { result.current.decrement(); }); expect(result.current.count).toBe(-1); }); ```æ³šïŒ React Testing Libraryã® `act` 颿°ã¯ããã£ã¹ãããåŒã³åºããã©ããããããã«äœ¿çšãããŸããããã«ãããã¢ãµãŒã·ã§ã³ãè¡ãããåã«ããã¹ãŠã®ç¶æ æŽæ°ãé©åã«ãããåŠçãããŠé©çšãããããšãä¿èšŒãããŸãã
5. ã³ãŒã«ããã¯ããã¯ïŒuseCallbackïŒã®ãã¹ã
ã³ãŒã«ããã¯ããã¯ã¯ãäžèŠãªåã¬ã³ããªã³ã°ãé²ãããã«é¢æ°ãã¡ã¢åããŸãããããã®ããã¯ããã¹ãããã«ã¯ãäŸåé¢ä¿ã倿ŽãããŠããªãå Žåã«ãã¬ã³ããªã³ã°éã§é¢æ°ã®ã¢ã€ãã³ãã£ãã£ãåããŸãŸã§ããããšã確èªããå¿ èŠããããŸãã
äŸïŒ
```javascript // useCallbackHook.js import { useState, useCallback } from 'react'; const useMemoizedCallback = () => { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount(prevCount => prevCount + 1); }, []); // Dependency array is empty return { count, increment }; }; export default useMemoizedCallback; ``` ```javascript // useCallbackHook.test.js import { renderHook, act } from '@testing-library/react'; import useMemoizedCallback from './useCallbackHook'; test('increment function remains the same', () => { const { result, rerender } = renderHook(() => useMemoizedCallback()); const initialIncrement = result.current.increment; act(() => { result.current.increment(); }); rerender(); expect(result.current.increment).toBe(initialIncrement); }); test('increments the count', () => { const { result } = renderHook(() => useMemoizedCallback()); act(() => { result.current.increment(); }); expect(result.current.count).toBe(1); }); ```6. Refããã¯ïŒuseRefïŒã®ãã¹ã
Refããã¯ã¯ãã¬ã³ããªã³ã°ããŸããã§æç¶ããå¯å€ã®åç §ãäœæããŸãããããã®ããã¯ããã¹ãããã«ã¯ãrefã®å€ãæ£ããæŽæ°ãããã¬ã³ããªã³ã°éã§ãã®å€ãä¿æããŠããããšã確èªããå¿ èŠããããŸãã
äŸïŒ
```javascript // useRefHook.js import { useRef, useEffect } from 'react'; const usePrevious = (value) => { const ref = useRef(); useEffect(() => { ref.current = value; }, [value]); return ref.current; }; export default usePrevious; ``` ```javascript // useRefHook.test.js import { renderHook } from '@testing-library/react'; import usePrevious from './useRefHook'; test('returns undefined on initial render', () => { const { result } = renderHook(() => usePrevious(1)); expect(result.current).toBeUndefined(); }); test('returns the previous value after update', () => { const { result, rerender } = renderHook((value) => usePrevious(value), { initialProps: 1 }); rerender(2); expect(result.current).toBe(1); rerender(3); expect(result.current).toBe(2); }); ```7. ã«ã¹ã¿ã ããã¯ã®ãã¹ã
ã«ã¹ã¿ã ããã¯ã®ãã¹ãã¯ãçµã¿èŸŒã¿ããã¯ã®ãã¹ããšäŒŒãŠããŸããéèŠãªã®ã¯ãããã¯ã®ããžãã¯ãåé¢ãããã®å ¥åãšåºåã®æ€èšŒã«éäžããããšã§ããã«ã¹ã¿ã ããã¯ã®æ©èœïŒç¶æ 管çãå¯äœçšãã³ã³ããã¹ãã®äœ¿çšãªã©ïŒã«å¿ããŠãäžèšã§è¿°ã¹ãæŠç¥ãçµã¿åãããããšãã§ããŸãã
ããã¯ããã¹ãããããã®ãã¹ããã©ã¯ãã£ã¹
Reactããã¯ããã¹ãããéã«å¿ã«çããŠããã¹ãäžè¬çãªãã¹ããã©ã¯ãã£ã¹ãããã€ã玹ä»ããŸãïŒ
- ãŠããããã¹ããæžãïŒ å€§ããªã³ã³ããŒãã³ãã®äžéšãšããŠãã¹ãããã®ã§ã¯ãªããããã¯ã®ããžãã¯ãåé¢ããŠãã¹ãããããšã«éäžããŸãã
- React Testing Libraryã䜿çšããïŒ React Testing Libraryã¯ãŠãŒã¶ãŒäžå¿ã®ãã¹ãã奚å±ãããã¹ãããŠãŒã¶ãŒã®ã³ã³ããŒãã³ããšã®å¯Ÿè©±æ¹æ³ãåæ ããããã«ããŸãã
- äŸåé¢ä¿ãã¢ãã¯ããïŒ APIåŒã³åºããã³ã³ããã¹ãå€ãªã©ã®å€éšäŸåé¢ä¿ãã¢ãã¯ããŠãããã¯ã®ããžãã¯ãåé¢ããå€éšèŠå ããã¹ãã«åœ±é¿ãäžããã®ãé²ããŸãã
- éåæãã¹ãæè¡ã䜿çšããïŒ ããã¯ãå¯äœçšãå®è¡ããå Žåã¯ã`waitFor`ã`findBy*`ã¡ãœãããªã©ã®éåæãã¹ãæè¡ã䜿çšããŠãã¢ãµãŒã·ã§ã³ãè¡ãåã«å¯äœçšãå®äºããã®ãåŸ ã¡ãŸãã
- ãã¹ãŠã®å¯èœãªã·ããªãªããã¹ãããïŒ ãã¹ãŠã®å¯èœãªå ¥åå€ããšããžã±ãŒã¹ããšã©ãŒæ¡ä»¶ãã«ããŒããŠãããã¯ããã¹ãŠã®ç¶æ³ã§æ£ããåäœããããšã確èªããŸãã
- ãã¹ããç°¡æœã§èªã¿ãããä¿ã€ïŒ çè§£ããããä¿å®ãããããã¹ããæžããŸãããã¹ããã¢ãµãŒã·ã§ã³ã«ã¯èª¬æçãªååã䜿çšããŸãã
- ã³ãŒãã«ãã¬ããžãèæ ®ããïŒ ã³ãŒãã«ãã¬ããžããŒã«ã䜿çšããŠãããã¯ã®ååã«ãã¹ããããŠããªãé åãç¹å®ããŸãã
- Arrange-Act-Assertãã¿ãŒã³ã«åŸãïŒ ãã¹ãã3ã€ã®æç¢ºãªãã§ãŒãºã«æŽçããŸãïŒArrangeïŒãã¹ãç°å¢ã®ã»ããã¢ããïŒãActïŒãã¹ããããã¢ã¯ã·ã§ã³ã®å®è¡ïŒãAssertïŒã¢ã¯ã·ã§ã³ãæåŸ ãããçµæãçã¿åºããããšã®æ€èšŒïŒã
é¿ããã¹ãäžè¬çãªèœãšã穎
Reactããã¯ããã¹ãããéã«é¿ããã¹ãäžè¬çãªèœãšã穎ãããã€ã玹ä»ããŸãïŒ
- å®è£ ã®è©³çްãžã®é床ãªäŸåïŒ ããã¯ã®å®è£ ã®è©³çްã«å¯çµåãããã¹ããæžãã®ã¯é¿ããŠãã ããããŠãŒã¶ãŒã®èŠç¹ããããã¯ã®åäœããã¹ãããããšã«éäžããŸãã
- éåæã®åäœãç¡èŠããïŒ éåæã®åäœãé©åã«åŠçããªããšãäžå®å®ãŸãã¯äžæ£ç¢ºãªãã¹ãã«ã€ãªããå¯èœæ§ããããŸããå¯äœçšã®ããããã¯ããã¹ãããéã¯ãåžžã«éåæãã¹ãæè¡ã䜿çšããŠãã ããã
- äŸåé¢ä¿ãã¢ãã¯ããªãïŒ å€éšã®äŸåé¢ä¿ãã¢ãã¯ããªããšããã¹ããè匱ã§ä¿å®ãå°é£ã«ãªãå¯èœæ§ããããŸããããã¯ã®ããžãã¯ãåé¢ããããã«ãåžžã«äŸåé¢ä¿ãã¢ãã¯ããŠãã ããã
- 1ã€ã®ãã¹ãã«å€ãã®ã¢ãµãŒã·ã§ã³ãæžããããïŒ 1ã€ã®ãã¹ãã«å€ãã®ã¢ãµãŒã·ã§ã³ãæžããšã倱æã®æ ¹æ¬åå ãç¹å®ããã®ãé£ãããªããŸããè€éãªãã¹ãã¯ãããå°ãããããçŠç¹ã®åã£ããã¹ãã«åå²ããŠãã ããã
- ãšã©ãŒæ¡ä»¶ããã¹ãããªãïŒ ãšã©ãŒæ¡ä»¶ããã¹ãããªããšãããã¯ãäºæãã¬åäœã«å¯ŸããŠè匱ã«ãªãå¯èœæ§ããããŸããããã¯ããšã©ãŒãäŸå€ãã©ã®ããã«åŠçããããåžžã«ãã¹ãããŠãã ããã
é«åºŠãªãã¹ãææ³
ããè€éãªã·ããªãªã«ã¯ããããã®é«åºŠãªãã¹ãææ³ãæ€èšããŠãã ããïŒ
- ããããã£ããŒã¹ããã¹ãïŒ å¹ åºãã©ã³ãã ãªå ¥åãçæããŠãæ§ã ãªã·ããªãªã«ãããããã¯ã®åäœããã¹ãããŸããããã«ãããåŸæ¥ã®ãŠããããã¹ãã§ã¯èŠéããã¡ãªãšããžã±ãŒã¹ãäºæãã¬åäœãçºèŠããã®ã«åœ¹ç«ã¡ãŸãã
- ãã¥ãŒããŒã·ã§ã³ãã¹ãïŒ ããã¯ã®ã³ãŒãã«å°ããªå€æŽïŒãã¥ãŒããŒã·ã§ã³ïŒãå ãããã®å€æŽãããã¯ã®æ©èœãå£ãããšãã«ãã¹ãã倱æããããšã確èªããŸããããã«ããããã¹ããå®éã«æ£ããããšããã¹ãããŠãããã確èªã§ããŸãã
- å¥çŽãã¹ãïŒ ããã¯ã®æåŸ ãããåäœãèŠå®ããå¥çŽãå®çŸ©ããããã¯ããã®å¥çŽãéµå®ããŠããããšãæ€èšŒãããã¹ããæžããŸããããã¯ãå€éšã·ã¹ãã ãšå¯Ÿè©±ããããã¯ããã¹ãããéã«ç¹ã«åœ¹ç«ã¡ãŸãã
çµè«
Reactããã¯ã®ãã¹ãã¯ãå ç¢ã§ä¿å®æ§ã®é«ãReactã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«äžå¯æ¬ ã§ãããã®ã¬ã€ãã§æŠèª¬ããæŠç¥ãšãã¹ããã©ã¯ãã£ã¹ã«åŸãããšã§ãããã¯ã培åºçã«ãã¹ããããã¢ããªã±ãŒã·ã§ã³ãä¿¡é Œæ§ãé«ãå埩åãããããšãä¿èšŒã§ããŸãããŠãŒã¶ãŒäžå¿ã®ãã¹ãã«çŠç¹ãåœãŠãäŸåé¢ä¿ãã¢ãã¯ããéåæã®åäœãåŠçãããã¹ãŠã®å¯èœãªã·ããªãªãã«ããŒããããšãå¿ããªãã§ãã ãããå æ¬çãªããã¯ãã¹ãã«æè³ããããšã§ãã³ãŒãã«èªä¿¡ãæã¡ãReactãããžã§ã¯ãå šäœã®å質ãåäžãããããšãã§ããŸããéçºã¯ãŒã¯ãããŒã®äžå¯æ¬ ãªéšåãšããŠãã¹ããåãå ¥ããã°ãããå®å®ãäºæž¬å¯èœãªã¢ããªã±ãŒã·ã§ã³ãšããå ±é ¬ãåŸãããã§ãããã
ãã®ã¬ã€ãã¯ãReactããã¯ããã¹ãããããã®åŒ·åºãªåºç€ãæäŸããŸãããçµéšãç©ãã«ã€ããŠãããŸããŸãªãã¹ãææ³ã詊ãããããžã§ã¯ãã®ç¹å®ã®ããŒãºã«åãããŠã¢ãããŒãã調æŽããŠãã ãããããããŒãã¹ãã£ã³ã°ïŒ