728x90
* 연습과제 2
import './App.css';
import React, { Component } from 'react'
class App extends Component {
state = {
numbers: ''
}
pickRandomNumber = (min, max) => { return Math.floor( Math.random() * (max-min+1) ) + min }
isDuplicated = (numbers, picked) => {
return numbers.find(num => num === picked)
}
getLottoNum = (numbers) => {
// console.log("length: ", numbers)
const picked = this.pickRandomNumber(1, 45)
const duplicatedNum = this.isDuplicated(numbers, picked) // 중복체크
if(duplicatedNum){
console.log('duplicated ...', duplicatedNum)
this.getLottoNum(numbers) // 로또배열에 랜덤으로 뽑은 숫자가 이미 존재하면 재귀적으로 다시 숫자를 뽑음
}else{
numbers.push(picked)
}
}
showRandomNumber = () => {
const numbers = [] // 로또번호 배열
while(numbers.length < 6){
this.getLottoNum(numbers)
}
this.setState({ numbers: numbers.join(' ')})
}
// 초기에 웹화면이 렌더링되었을때 타이머를 설정함
componentDidMount(){
this.countID = setInterval(this.showRandomNumber, 1000)
}
// 사용자가 웹화면을 벗어나면 타이머를 해제함
componentWillUnmount(){
clearInterval(this.countID)
}
render(){
const { numbers } = this.state
return (
<div className='App'>
<h1>로또번호 자동 생성기</h1>
<h1>{numbers}</h1>
</div>
)
}
}
export default App;
* 연습과제 3
import './App.css';
import { Component } from 'react';
import words from './dummyData'
class App extends Component {
state = {
number: 0,
}
pickRandomNumber = (min, max) => {
return Math.floor( Math.random() * (max-min+1) ) + min
}
setNumber = () => {
this.setState({ number: this.pickRandomNumber(0, words.length-1)})
}
componentDidMount(){
this.countID = setInterval(
this.setNumber
, 1000)
}
componentWillUnmount(){
clearInterval(this.countID)
}
render(){
const cardStyle = {
background: 'tan',
width: '30%',
margin: 'auto',
padding: '20px'
}
const { number } = this.state
const word_picked = words[number]
console.log(words.length, number)
return (
<div className="App">
<h1>Flash card</h1>
<div style={cardStyle}>
<h2>{word_picked.word}</h2>
<h3>{word_picked.meaning}</h3>
</div>
</div>
);
}
}
export default App;
* 연습과제 4
import './App.css';
import React, { Component } from 'react'
class App extends Component{
state = {
isSorted: false,
products: null,
sortedProducts: null
}
componentDidMount(){
const API_URL = 'http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline'
// 서버에서 데이터 가져오기
fetch(API_URL)
.then((res) => {
return res.json()
})
.then((products) => {
const sortedProducts = [...products] // 원본복사
sortedProducts.sort( (p1, p2) => parseFloat(p1.price) - parseFloat(p2.price) )
this.setState({products, sortedProducts})
})
}
toggleState = () => {
this.setState({ isSorted: !this.state.isSorted})
}
render(){
const { isSorted, products, sortedProducts } = this.state
const displayProducts = (product) => {
const item = (
<div key={product.id} className='product'>
<div className='product-img'><img src={product.image_link} alt={product.name}/></div>
<div className='product-name'>{product.name} (${product.price})</div>
<div className='product-description'>{product.description}</div>
<div className='product-type'>{product.product_type}</div>
</div>
)
return item
}
return (
<>
<div className="header">
<button className="sort-btns" onClick={this.toggleState}>Price</button><br/>
</div>
<div className='root'>
{isSorted ?
sortedProducts && sortedProducts.map(displayProducts)
: products && products.map(displayProducts)}
</div>
</>
)
}
}
export default App;
.header{
width: 100%;
height: 70px;
position: fixed;
left: 0;
top: 0;
right: 0;
box-shadow: 1px 1px 5px 5px darkgray;
background: white;
z-index: 1;
display: flex;
justify-content: flex-end;
align-items: center;
}
.sort-btns{
all: unset;
width: 100px;
height: 50px;
background: peru;
border-radius: 10px;
cursor: pointer;
color: white;
font-size: 1rem;
font-weight: bold;
text-align: center;
margin-right: 10px;
}
.sort-btns:hover{
opacity: 0.8;
}
.root{
width: 60%;
margin: 100px auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.product{
flex: 200px;
height: 500px;
box-shadow: 1px 1px 5px 5px peru;
color: white;
background: peru;
margin: 10px;
overflow: hidden;
}
.product-img{
width: 100%;
height: 180px;
overflow: hidden;
}
.product-img img{
width: 100%;
height: 100%;
}
.product-name{
font-weight: bold;
font-size: 1.1rem;
text-align: center;
}
.product-description{
font-weight: 400;
font-size: 0.9rem;
text-align: center;
margin-top: 15px;
}
* 연습과제 5
import './App.css';
import React, { Component } from 'react'
class App extends Component{
state = {
todos: []
}
componentDidMount(){
const API_URL = 'http://localhost:5000/api/todos'
// 서버에서 데이터 가져오기
fetch(API_URL)
.then((res) => {
return res.json()
})
.then((data) => {
this.setState({todos: data.todos})
})
}
render(){
const { todos } = this.state
console.log(todos)
return (
<>
<div className='App'>
{todos.length !== 0 && todos.map( todo => {
return (
<div key={todo._id}>
<h1>{todo.name} ({todo.done ? "종료" : "진행중"})</h1>
<h2>{todo.description}</h2>
<h2>-------------------------------</h2>
</div>
)
})}
</div>
</>
)
}
}
export default App;
728x90
'프론트엔드 > React 연습과제 해답' 카테고리의 다른 글
리액트 기초이론 5 - 컴포넌트 스타일링 2 - SASS 해답 (0) | 2022.03.02 |
---|---|
리액트 기초이론 5 - 컴포넌트 스타일링 해답 (0) | 2022.02.28 |
리액트 기초이론 3 - JSX 문법 해답 (0) | 2022.02.21 |
리액트 기초이론 2 - state & props 해답 (0) | 2022.02.17 |
리액트 기초이론 1 - 클래스형 컴포넌트 & 함수형 컴포넌트 해답 (0) | 2022.02.16 |