React - Monster

๐Ÿ‘พ Task 1. API ํ˜ธ์ถœ

  1. ์œ„ ์ฃผ์†Œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ์„ ์ฒ˜๋ฆฌํ•ด์ฃผ์„ธ์š”!
- componentDidMount()
- fetch
- setState (monsters ์— ์ €์žฅ)
  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users", {
      method: "GET",
    })
      .then((res) => res.json())
      .then((data) => {
        this.setState({
          monsters: data,
        });
      });
  }

๐Ÿ‘พ Task 2. API ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๊ฐ’ props ๋กœ ์ž์‹์—๊ฒŒ ์ „๋‹ฌ

  • API ํ˜ธ์ถœ ํ›„ ์ €์žฅํ•œ ๋ฐฐ์—ด์„ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์ธ <CardList /> ์— ๋„˜๊ฒจ์ฃผ์„ธ์š”. (props ํ™œ์šฉ)
  • ๋„˜๊ฒจ์ค€ ํ›„ CardList.js ์—์„œ props ๋ฅผ ์ฝ˜์†”์— ์ฐ์–ด ํ™•์ธํ•ด์ฃผ์„ธ์š”.
// Monsters.js
  render() {
    return (
      <div className="Monsters">
        <h1>์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ ์—ฐ์Šต!</h1>
        <CardList monsters={monsterFilter} />
      </div>
    );
  }
}

๐Ÿ‘พ Task 3. Array.map( ) ์‚ฌ์šฉ

  • ๋„˜๊ฒจ๋ฐ›์€ ๋ฐฐ์—ด์„ ๊ธฐ์ค€์œผ๋กœ Array.map() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ <Card /> ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ์„ธ์š”.
  • Card.js ์—๊ฒŒ ๋„˜๊ฒจ์ค˜์•ผํ•˜๋Š” props ๋Š” ๊ฐ ๋ชฌ์Šคํ„ฐ ๊ฐ์ฒด์˜ id, name, email ์ž…๋‹ˆ๋‹ค.
class CardList extends Component {
  render() {
    //ES6 ๊ฐ์ฒด, ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น
    const { monsters } = this.props;
    return (
      <div className="card-list">
        {monsters.map((monster) => {
          return (
            <Card
              key={monster.id}
              id={monster.id}
              name={monster.name}
              email={monster.email}
            />
          );
        })}
      </div>
    );
  }
}

๐Ÿ‘พ Task 4. props ํ™œ์šฉ

Card ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ

	<img src=์ด๋ฏธ์ง€์ฃผ์†Œ alt="">
  	<h2>Name</h2>
	<p>Email</p>
class Card extends Component {
  render() {
    const { id, name, email } = this.props;
    return (
      <div className="card-container">
        <img
          src={`https://robohash.org/${id}?set=set2&size=180x180`}
          alt="moster"
        ></img>
        <h2>{name}</h2>
        <p>{email}</p>
      </div>
    );
  }
}

๐Ÿ‘พ Task 5. ํ•„ํ„ฐ๋ง ๋กœ์ง ๊ตฌํ˜„(filter ๋ฉ”์†Œ๋“œ ํ™œ์šฉ)

  • ์—ฌ๊ธฐ์„œ ๋น„๊ต ๋Œ€์ƒ์€ monster ๊ฐ์ฒด์˜ name ๊ฐ’์ž…๋‹ˆ๋‹ค.
  • ์†Œ๋ฌธ์ž๋กœ ๋ฐ”๊พผ monster.name ๊ฐ’๊ณผ userInput๊ฐ’์„ ๋น„๊ต.
  • filter ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์„ ๋ณ€์ˆ˜์— ์ €์žฅ ํ›„ return ๋ฌธ ์•ˆ์— CardList์— props๋กœ ์ „๋‹ฌ
// SearchBox ์— props๋กœ ๋„˜๊ฒจ์ค„ handleChange ๋ฉ”์†Œ๋“œ ์ •์˜
handleChange = (e) => {
  this.setState({
    userInput: e.target.value,
  });
};
// SearchBox.js
class SearchBox extends Component {
  render() {
    return (
      <input
        className="search"
        type="search"
        placeholder="Search..."
        onChange={this.props.handleChange}
      />
    );
  }
}
// Monsters.js
  render() {
    const monsterFilter = this.state.monsters.filter((monster) =>
      monster.name.toLowerCase().includes(this.state.userInput.toLowerCase())
    );
    return (
      <div className="Monsters">
        <h1>์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ ์—ฐ์Šต!</h1>
        <SearchBox handleChange={this.handleChange} />
        <CardList monsters={monsterFilter} />
      </div>
    );
  }
}