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

랜더함수 리팩토링(인프런 김정환)

by warrior.p 2022. 4. 2.

 

 

리팩토링 전

import store from './js/store.js';

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

    this.state = {
      searchKeyword: '',
      searchResult: [],
      submitted: false,
    };
  }

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

  search(searchKeyword) {
    const searchResult = store.search(searchKeyword);
    this.setState({ searchResult, submitted: true });
  }

  //검색결과를 삭제하는 로직
  handleReset() {
    //setState()는 항상 비동기적(여러번 호출 하더라도 최소한의 변경을 위해서)
    // this.setState({ searchKeyword: '' });
    this.setState(
      () => {
        return { searchKeyword: '' };
      },
      () => {
        console.log('TODO:handleReset', this.state.searchKeyword);
      }
    );
  }

  handleChangeInput(event) {
    // this.state.searchKeyword = event.target.value;   X
    // this.forceUpdate();    X
    //컴포넌트 상태를 변경하려면 직접 수정하지 말고 컴포넌트class가 제공하는 set메소드를 사용해라!
    //컴포넌트의 상태를 변화시키겠다는 컴포넌트와의 직접적인 약속. 잊지말자 setState()
    const searchKeyword = event.target.value;

    if (searchKeyword.length <= 0) {
      return this.handleReset();
    }

    this.setState({ searchKeyword });
  }

  render() {
    return (
      <>
        <header>
          <h2 className='container'>검색</h2>
        </header>
        <div className='container'>
          <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>
          <div className='content'>
            {/* 검색 결과를 출력하는 부분 */}
            {this.state.submitted &&
              (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>
              ))}
          </div>
          {/* -결과출력 - */}
        </div>
      </>
    );
  }
}

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

 

 

리팩토링 후

import store from './js/store.js';

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

    this.state = {
      searchKeyword: '',
      searchResult: [],
      submitted: false,
    };
  }

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

  search(searchKeyword) {
    const searchResult = store.search(searchKeyword);
    this.setState({ searchResult, submitted: true });
  }

  //검색결과를 삭제하는 로직
  handleReset() {
    //setState()는 항상 비동기적(여러번 호출 하더라도 최소한의 변경을 위해서)
    // this.setState({ searchKeyword: '' });
    this.setState(
      () => {
        return { searchKeyword: '' };
      },
      () => {
        console.log('TODO:handleReset', this.state.searchKeyword);
      }
    );
  }

  handleChangeInput(event) {
    // this.state.searchKeyword = event.target.value;   X
    // this.forceUpdate();    X
    //컴포넌트 상태를 변경하려면 직접 수정하지 말고 컴포넌트class가 제공하는 set메소드를 사용해라!
    //컴포넌트의 상태를 변화시키겠다는 컴포넌트와의 직접적인 약속. 잊지말자 setState()
    const searchKeyword = event.target.value;

    if (searchKeyword.length <= 0) {
      return this.handleReset();
    }

    this.setState({ searchKeyword });
  }

  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>
      );

    return (
      <>
        <header>
          <h2 className='container'>검색</h2>
        </header>
        <div className='container'>
          {searchForm}
          <div className='content'>
            {/* 검색 결과를 출력하는 부분 */}
            {this.state.submitted && searchResult}
          </div>
          {/* -결과출력 - */}
        </div>
      </>
    );
  }
}

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

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

자습서 - 게임  (0) 2022.05.09
리액트 사용편  (0) 2022.04.05
Habit Tracker 만들기  (0) 2022.03.20