본문 바로가기
Front-end/React 실습

리액트 사용편

by warrior.p 2022. 4. 5.
import { formatRelativeDate } from './js/helpers.js';
import store from './js/store.js';

const TabType = {
  KEYWORD: 'KEYWORD',
  HISTORY: 'HISTORY',
};

const TabLabel = {
  [TabType.KEYWORD]: '추천 검색어',
  [TabType.HISTORY]: '최근 검색어',
};

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      searchKeyword: '',
      searchResult: [],
      submitted: false,
      selectedTab: TabType.KEYWORD,
      keywordList: [], //추천검 색어 리스트
      historyList: [], //최근 검색어 리스트
    };
  }

  componentDidMount() {
    const keywordList = store.getKeywordList(); //store.js에 있는 keyWordList를 가져오는
    const historyList = store.getHistoryList();

    this.setState({
      //상태 업데이트
      keywordList,
      historyList,
    });
  }

  handleSubmit(event) {
    event.preventDefault();
    console.log('TODO:handleSubmit', this.state.searchKeyword);
    this.search(this.state.searchKeyword);
  }

  search(searchKeyword) {
    const searchResult = store.search(searchKeyword);
    const historyList = store.getHistoryList();

    this.setState({
      searchKeyword,
      searchResult,
      historyList,
      submitted: true,
    });
  }

  handleReset() {
    //setState()는 항상 비동기적(여러번 호출 하더라도 최소한의 변경을 위해서)
    this.setState({
      searchKeyword: '',
      submitted: false,
    });
  }

  //검색어 입력을 처리하는 부분
  handleChangeInput(event) {
    //컴포넌트 상태를 변경하려면 직접 수정하지 말고 컴포넌트class가 제공하는 set메소드를 사용해라!
    //컴포넌트의 상태를 변화시키겠다는 컴포넌트와의 직접적인 약속. 잊지말자 setState()
    const searchKeyword = event.target.value;
    if (searchKeyword.length <= 0 && this.state.submitted) {
      return this.handleReset();
    }

    this.setState({ searchKeyword });
  }

  handleClickRemoveHistory(event, keyword) {
    event.stopPropagation(); //버블링을 막는 함수!

    store.removeHistory(keyword);
    const historyList = store.getHistoryList();
    this.setState({ historyList });
  }

  render() {
    const searchForm = (
      <form
        onSubmit={event => this.handleSubmit(event)}
        onReset={() => this.handleReset()}
      >
        <input
          type='text'
          placeholder='검색어를 입력하세요'
          autoFocus
          value={this.state.searchKeyword}
          onChange={event => this.handleChangeInput(event)}
        />
        {this.state.searchKeyword.length > 0 && (
          <button type='reset' className='btn-reset'></button>
        )}
      </form>
    );

    const searchResult =
      this.state.searchResult.length > 0 ? (
        <ul className='result'>
          {this.state.searchResult.map(item => {
            return (
              <li key={item.id}>
                <img src={item.imageUrl} alt={item.name} />
                <p>{item.name}</p>
              </li>
            );
          })}
        </ul>
      ) : (
        <div className='empty-box'>검색 결과가 없습니다</div>
      );

    const keywordList = (
      <ul className='list'>
        {this.state.keywordList.map(({ id, keyword }, index) => (
          <li key={id} onClick={() => this.search(keyword)}>
            <span className='number'>{index + 1}</span>
            <span>{keyword}</span>
          </li>
        ))}
      </ul>
    );

    const historyList = (
      <ul className='list'>
        {this.state.historyList.map(({ id, keyword, date }) => (
          <li key={id} onClick={() => this.search(keyword)}>
            <span>{keyword}</span>
            <span className='date'>{formatRelativeDate(date)}</span>
            <button
              className='btn-remove'
              onClick={event => this.handleClickRemoveHistory(event, keyword)}
            />
          </li>
        ))}
      </ul>
    );

    const tabs = (
      <>
        <ul className='tabs'>
          {Object.values(TabType).map(TabType => (
            <li
              className={this.state.selectedTab === TabType ? 'active' : ''}
              key={TabType}
              onClick={() => this.setState({ selectedTab: TabType })}
            >
              {TabLabel[TabType]}
            </li>
          ))}
        </ul>
        {this.state.selectedTab === TabType.KEYWORD && keywordList}
        {this.state.selectedTab === TabType.HISTORY && historyList}
      </>
    );

    return (
      <>
        <header>
          <h2 className='container'>검색</h2>
        </header>
        <div className='container'>
          {searchForm}
          <div className='content'>
            {this.state.submitted ? searchResult : tabs}
          </div>
        </div>
      </>
    );
  }
}

ReactDOM.render(<App />, document.querySelector('#app'));

'Front-end > React 실습' 카테고리의 다른 글

자습서 - 게임  (0) 2022.05.09
랜더함수 리팩토링(인프런 김정환)  (0) 2022.04.02
Habit Tracker 만들기  (0) 2022.03.20