-
리액트 기초이론 5 - 컴포넌트 스타일링 2 - SASS 해답프론트엔드/React 연습과제 해답 2022. 3. 2. 13:15728x90
* 연습과제 1
import React from 'react' import './Button.scss' function Button({ children, size, color, width, handleClick, disabled }){ return <button className={`Button ${size} ${color} ${width}`} onClick={handleClick} disabled={disabled} >{children}</button> } export default Button; Button.defaultProps = { size: 'medium', color: 'tomato', disabled: false }
@use "sass:list"; $colors: blue, tomato, grey; $hover-colors: skyblue, lightsalmon, lightgray; $sizes: large, medium, small; $default-height: 50px; $default-padding-left: 10px; $default-padding-right: 10px; $default-font-size: 1rem; @mixin setBtnSize($size, $h, $pl, $pr, $fs){ .#{$size}{ height: $h; padding-left: $pl; padding-right: $pr; font-size: $fs; } } .Button { all: unset; color: white; cursor: pointer; border-radius: 5px; font-weight: bold; margin-left: 10px; display: inline-flex; align-items: center; justify-content: center; &:hover{ opacity: 0.7; } } /* 버튼의 크기 설정 */ @include setBtnSize(list.nth($sizes, 1), $default-height + 20px , $default-padding-left + 5px, $default-padding-right + 5px, $default-font-size + 0.2rem); @include setBtnSize(list.nth($sizes, 2), $default-height , $default-padding-left, $default-padding-right, $default-font-size); @include setBtnSize(list.nth($sizes, 3), $default-height - 20px , $default-padding-left - 5px, $default-padding-right - 5px, $default-font-size - 0.2rem); /* 버튼의 배경색 설정 */ @each $color in $colors{ .#{$color}{ background: $color; &:hover{ background: list.nth($hover-colors, list.index($colors, $color)); } } } /* 전체 너비를 차지하는 버튼 */ .fullWidth{ width: 100%; margin-left: 0px; margin-top: 10px; margin-bottom: 10px; }
* 연습과제 2
import React from 'react' import './Modal.scss' function Modal({ open, children }){ return <div className={`Modal ${open? "open": "close"}`}>{children}</div> } export default Modal; Modal.defaultProps = { open: false }
$modal-func: ( open: block, close: none ); $modal-style: ( header: ( font-size: 1.2rem, font-weight: bold ), body: ( font-size: 0.9rem, margin: 20px ), 'body input': ( width: 60%, height: 30px, border: 1px solid lightgray, border-radius: 5px, margin-bottom: 10px ), footer: ( display: flex, justify-content: flex-end, align-items: center ) ); .Modal { width: 500px; margin: 100px auto; border: 1px solid tan; padding: 10px; text-align: center; } // 모달창 열고 닫기 @each $key, $value in $modal-func{ .#{$key}{ display: $value; } } // 모달창 스타일링 @each $classname, $attributes in $modal-style{ .#{$classname}{ @if($classname != 'body input'){ padding: 5px; } @each $key, $value in $attributes{ #{$key}: $value; } } }
* 연습과제 3
import './App.scss'; 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;
$primary-bg-color: peru; $primary-color: white; @mixin setPosition($jc, $ai, $fw){ display: flex; flex-wrap: $fw; justify-content: $jc; align-items: $ai; } @mixin setFont($size, $weight){ font-size: $size; font-weight: $weight; text-align: center; } @mixin setSize($width, $height){ @if($width) { width: $width; } @if($height) { height: $height; } } @mixin setColor($bgc, $c){ @if($bgc) { background: $bgc; } @if($c) { color: $c; } } .header{ @include setSize(100%, 70px); @include setPosition(flex-end, center, nowrap); @include setColor($primary-color, null); position: fixed; left: 0; top: 0; right: 0; box-shadow: 1px 1px 5px 5px darkgray; z-index: 1; .sort-btns{ all: unset; @include setSize(100px, 50px); @include setFont(1rem, bold); @include setColor($primary-bg-color, $primary-color); border-radius: 10px; cursor: pointer; margin-right: 10px; &:hover{ opacity: 0.8; } } } .root{ @include setSize(60%, null); @include setPosition(center, center, wrap); margin: 100px auto; .product{ @include setSize(null, 500px); @include setColor($primary-bg-color, $primary-color); flex: 200px; box-shadow: 1px 1px 5px 5px $primary-bg-color; margin: 10px; overflow: hidden; .product-img{ @include setSize(100%, 180px); overflow: hidden; img{ @include setSize(100%, 100%); } } .product-name{ @include setFont(1.1rem, bold); } .product-description{ @include setFont(0.9rem, 400); margin-top: 15px; } } }
728x90'프론트엔드 > React 연습과제 해답' 카테고리의 다른 글
리액트 기초이론 7 - 이벤트(Event) 처리하기 해답 (0) 2022.03.09 리액트 기초이론 5 - 컴포넌트 스타일링 3 - Styled Components 해답 (0) 2022.03.07 리액트 기초이론 5 - 컴포넌트 스타일링 해답 (0) 2022.02.28 리액트 기초이론 4 - 컴포넌트의 생명주기 (Life cycle) 해답 (0) 2022.02.23 리액트 기초이론 3 - JSX 문법 해답 (0) 2022.02.21