⚛️

React Patterns Wiki

커뮤니티 위키 & 포럼

⚛️

카테고리

프론트엔드 개발

최근 수정

2024년 1월

기여자

활성 기여자 42명

관련 주제

HTMLJavaScriptWeb Design

Tips, tricks, and best practices for React development

Custom Hooks Pattern

Extract reusable logic into custom hooks to keep components clean and promote code reuse across your application.

// useLocalStorage hook
function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      return initialValue;
    }
  });

  const setValue = (value) => {
    try {
      setStoredValue(value);
      window.localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error(error);
    }
  };

  return [storedValue, setValue];
}

// Usage
function Component() {
  const [name, setName] = useLocalStorage('name', 'Anonymous');
  return <input value={name} onChange={(e) => setName(e.target.value)} />;
}

Compound Components

Create flexible component APIs by splitting functionality across multiple components that work together.

// Compound component pattern
function Select({ children, value, onChange }) {
  return (
    <SelectContext.Provider value={{ value, onChange }}>
      <div className="select">{children}</div>
    </SelectContext.Provider>
  );
}

function Option({ value, children }) {
  const { value: selectedValue, onChange } = useContext(SelectContext);
  return (
    <button
      className={selectedValue === value ? 'active' : ''}
      onClick={() => onChange(value)}
    >
      {children}
    </button>
  );
}

// Usage
<Select value={selected} onChange={setSelected}>
  <Option value="a">Option A</Option>
  <Option value="b">Option B</Option>
</Select>

Render Props

Pass a function as a prop to share code between components while giving consumers full control over rendering.

// DataFetcher with render prop
function DataFetcher({ url, render }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(data => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return render({ data, loading });
}

// Usage
<DataFetcher
  url="/api/users"
  render={({ data, loading }) => (
    loading ? <Spinner /> : <UserList users={data} />
  )}
/>

토론 (0)

내 아바타

의견을 남겨 주세요

아직 댓글이 없습니다. 첫 번째 토론을 시작해 보세요!