[React] HOC 고차 컴포넌트

lim1313·2022년 2월 18일
0

TIL

목록 보기
19/22

HOC

HOC는 리액트 컴포넌트를 인자로 받아서 새로운 리액트 컴포넌트를 리턴하는 함수이다.

HOC 예제 1

App.jsx

import './App.css';
import User from './components/User';
import withCurrent from './components/withCurrent';

const CurrentUser = withCurrent(User);

function App() {
  return (
    <div>
      <CurrentUser userName="uey" />
    </div>
  );
}

export default App;

withCurrent.jsx

import React, { useEffect, useState } from 'react';

function withCurrent(Component) {
  const NewComponent = ({ userName, props }) => {
    const [user, setUser] = useState('');

    useEffect(() => {
      let timer = setTimeout(() => {
        setUser(userName);

        clearTimeout(timer);
      }, 1000);
    });

    if (!user) return 'Loading';

    return <Component {...props} user={user} />;
  };

  return NewComponent;
}

export default withCurrent;

User.jsx

import React from 'react';

function User({ user }) {
  return (
    <div>
      <strong>{user}</strong>
    </div>
  );
}

export default User;

HOC 예제 2

App.jsx

import './App.css';
import SerachTodos from './components/TodoList';
import SearchUsers from './components/UserList';

function App() {
  return (
    <div className="App">
      <h2>higer order component</h2>
      <div className="section">
        <div>
          <SearchUsers />
        </div>
        <div>
          <SerachTodos />
        </div>
      </div>
    </div>
  );
}

export default App;

withHOC.jsx

import React, { useEffect, useState } from 'react';

function withHOC(WrappedComponent, entity) {
  return function () {
    const [data, setData] = useState([]);
    const [term, setTerm] = useState('');

    useEffect(() => {
      const timer = setTimeout(() => {
        let fetchData =
          entity === 'users'
            ? [
                { name: 'yeji', id: 1 },
                { name: 'yoyo', id: 2 },
                { name: 'jojo', id: 3 },
                { name: 'aoao', id: 4 },
              ]
            : [
                { id: 1, userId: 1, title: 'hello', completed: true },
                { id: 2, userId: 2, title: 'bye', completed: true },
                { id: 3, userId: 3, title: 'mornign', completed: false },
                { id: 4, userId: 4, title: 'night', completed: false },
              ];

        setData([...fetchData]);

        clearTimeout(timer);
      }, 2000);
    }, []);

    let filterData = data.filter((d) => {
      if (entity === 'users') {
        const { name } = d;
        return name.indexOf(term) >= 0;
      }

      if (entity === 'todos') {
        const { title } = d;
        return title.indexOf(term) >= 0;
      }
    });

    return (
      <div>
        <h2>{entity}</h2>
        <input
          type="text"
          value={term}
          onChange={(e) => setTerm(e.target.value)}
        />
        <WrappedComponent data={filterData}></WrappedComponent>
      </div>
    );
  };
}

export default withHOC;

TodoList.jsx / UserList.jsx

import React, { useEffect, useState } from 'react';
import withHOC from './HOC';

function TodoLIst({ data }) {
  let renderTodos = data.map((todo) => {
    return (
      <div key={todo.id}>
        <p>
          <strong>{todo.title}</strong>
        </p>
      </div>
    );
  });

  return (
    <div>
      <div>{renderTodos}</div>
    </div>
  );
}

const SerachTodos = withHOC(TodoLIst, 'todos');

export default SerachTodos;

import React, { useEffect, useState } from 'react';
import withHOC from './HOC';

function UserList({ data }) {
  let renderUsers = data.map((user) => {
    return (
      <div key={user.id}>
        <p>
          <strong>{user.name}</strong>
        </p>
      </div>
    );
  });

  return (
    <div>
      <div>{renderUsers}</div>
    </div>
  );
}

const SearchUsers = withHOC(UserList, 'users');

export default SearchUsers;

참고

예제1 고차 컴포넌트
예제2 React 고차 컴포넌트 튜토리얼

profile
start coding

0개의 댓글