[React] Day5 - Todo / 프로필 이미지

윤수인·2024년 3월 21일
0

📒국비학원 [React]

목록 보기
4/14
post-thumbnail

1. Todo 리스트

✏️ Test1.

💻 입력


📂 todos 폴더 만들기

❗[리액트에 쓸 수 있는] 아이콘 사이트

:https://react-icons.github.io/react-icons/

사용방법

npm 모듈 설치

npm install react-icons --save


❗ 특수기호 사이트

: https://html.spec.whatwg.org/multipage/named-characters.html

  • 예시

  • 쓰레기통 가져오기

  • 플러스 가져오기

todo/item = 사용자 정의 변수임


⬇️ Todos.js

import React, { useRef, useState } from 'react';
import './Todos.css'
import TodoInput from './TodoInput';
import TodoList from './TodoList';

const Todos = () => {

    const no = useRef(1)

    const [todos,setTodos] = useState([
       
    ])

    const onAdd = (text) => {
        setTodos([
            ...todos,
            {
                id:no.current++,
                text, //text:text
                done:false
            }
        ])
    }


    const onDel = (id) => {
        setTodos(todos.filter(item => item.id!==id))
    }

    const onToggle = (id) => {
        
        /*
        setTodos(todos.map(item => {
            if(item.id===id){
                return{
                    ...item,
                    done:!item.done
                }
            }else{
                return item
            }
        }))
        */

        setTodos(todos.map(item=>item.id===id?{...item,done:!item.done}:item))

    }


    return (
        <div className='Todos'>
            <h1>Todo List</h1>
            <TodoInput onAdd={onAdd}/>
            <TodoList todos={todos} onDel={onDel} onToggle={onToggle}/>
        </div>
    );
};

export default Todos;

⬇️ TodoList.js

import React from 'react';
import './TodoList.css'
import TodoItem from './TodoItem';

const TodoList = ({todos,onDel,onToggle}) => {
    return (
        <ul className='TodoList'>
            {
                todos.map(item => <TodoItem key={item.id} item={item} onDel={onDel} onToggle={onToggle}/>)
            }
            <br/>
        </ul>
    );
};

export default TodoList;

⬇️ TodoItem.js

import React from 'react';
import { FaRegTrashAlt } from "react-icons/fa";
import {
    MdOutlineCheckBox,
    MdOutlineCheckBoxOutlineBlank 
} from "react-icons/md";

const TodoItem = ({item,onDel,onToggle}) => {

    const {id,text,done} = item

    return (
        <li className={done? 'on' : ''}>
            <span onClick={() => onToggle(id)}>
                {done ? <MdOutlineCheckBox/> : <MdOutlineCheckBoxOutlineBlank/>}

            </span>
            <em>{text}</em>
            <button onClick={() => onDel(id)}>
                <FaRegTrashAlt color='rgb(175,169,169)' size='20'/>
            </button>
         
        </li>
    );
};

export default TodoItem;

⬇️ TodoInput.js

import React, { useRef, useState } from 'react';
import './TodoInput.css'
import { MdAddCircle } from "react-icons/md";

const TodoInput = ({onAdd}) => {

    const textRef = useRef()

    const [text,setText] = useState('')

    const changeInput = (evt) => {
        const {value} = evt.target
        setText(value)
    }

    const onSubmit = (evt) => {

        evt.preventDefault()

        //입력창이 null이면  아래  onAdd(text) 실행하지마
        if(!text) return

        onAdd(text)

        setText('')
        textRef.current.focus()

    }

    return (
        <form className='TodoInput' onSubmit={onSubmit}>
            <br/>
            <input type='text' value={text} onChange={changeInput} ref={textRef}/>
            <button><MdAddCircle className='icon' size='50'/></button>
        </form>
    );
};

export default TodoInput;

✅ 결과


❗삭제


완료되면 줄 긋기 ------

  • 테스트용


  • 삼항연산자로도 토글 가능


✅ 결과

: 토글키 (toggle)

2. 프로필 이미지

✏️ Test2.

💻 입력


📂C:\VSCode\react>yarn create react-app test9 폴더만들기


❗랜덤이미지 제공 사이트


✅ insert 결과

✅ delete 삭제 결과

3. 1000자리마다 쉼표 / 영화 분석표

✏️ Test3.

💻 입력


1000자리마다 쉼표찍기 모듈 설치
: http://numeraljs.com/

npm -> install
yarn -> add


아이콘 모듈 설치

예시

예시 (영화) 약어

이미지 : thumbUrl
영화명 : movieNm
개봉일 : openDt
제작상태 : moviePrdtStat
영화구분 : movieType
관람등급 : watchGradeNm
상영시간 : showTs
제작국가 : repNationCd
감독 : director
장르 : genre
배급사 : dtNm
영화명 : movieNm
매출액 : salesAmt
관객수 : audiCnt
증감 : rankInten


⬇️Movies.js

import React,{useState} from 'react';
import movie from '../assets/api/movie.json'
import './style.css'
import MovieView from './MovieView';
import MovieList from './MovieList';
import Modal from './Modal';

const Movies = () => {

    const [data,setData] = useState(movie)
    const [movieInfo,setMovieInfo] = useState(data[0])

    const [isShow,setIsShow] = useState(false)

    const onOver = (id) => {
        const num = data.findIndex((item) => item.rank === id);
        setMovieInfo(data[num]);
    };

    const onOpen = () => {
        setIsShow(true)
    }
    
    const onClose = () => {
        setIsShow(false)

    }

    return (
        <>
            <div className='gallery'>
                <MovieView movieInfo={movieInfo} onOpen={onOpen}/>
                <MovieList data={data} onOver={onOver}/>
            </div>

            {
                isShow && <Modal onClose={onClose} movieInfo={movieInfo}/>
            }
        </>
    );
};

export default Movies;

⬇️MovieList.js


import React from 'react';
import MovieItem from './MovieItem';

const MovieList = ({data,onOver}) => {
    return (
        <div className='list'>
            <table>
                <colgroup>
                    <col className='w1'/>
                    <col className='w2'/>
                    <col className='w3'/>
                    <col className='w4'/>
                    <col className='w5'/>
                </colgroup>
                <thead>
                    <tr>
                        <th>순위</th>
                        <th>영화명</th>
                        <th>매출액</th>
                        <th>관객수</th>
                        <th>증감률</th>
                    </tr>
                </thead>
                <tbody>
                    {
                        data.map(item => <MovieItem key={item.rank} item={item} onOver={onOver}/>)
                    }
                </tbody>
            </table>
            
        </div>
    );
};

export default MovieList;


⬇️MovieItem.js

import React from 'react';
import Numeral from 'numeral'
import {
    AiOutlineCaretUp,
    AiOutlineCaretDown,
    AiOutlineMinus 
} from "react-icons/ai";

const MovieItem = ({item,onOver}) => {

    const {rank,movieNm,salesAmt,audiCnt,rankInten} = item


    return (
        <tr onMouseOver={() => onOver(rank)}>
            <td>{rank}</td>
            <td>{movieNm}</td>
            <td>{Numeral(salesAmt).format('0,0')}</td> 
            <td>{Numeral(audiCnt).format('0,0')}</td> 
            <td>
            {rankInten}
            {rankInten===0 && <AiOutlineMinus/>}
            {rankInten>0 && <AiOutlineCaretUp color='red'/>}
            {rankInten<0 && <AiOutlineCaretDown style={{color:'blue'}}/>}

            </td>
        </tr>
    );
};

export default MovieItem;


⬇️MovieView.js

import React from 'react';

const MovieView = ({movieInfo,onOpen}) => {

    const {thumbUrl,movieNm,openDt,moviePrdtStat,movieType,watchGradeNm,showTm,repNationCd,director,genre,dtNm} = movieInfo

    return (
        <div className='view' onClick={onOpen}>
            <img src={thumbUrl} alt={movieNm}/>
            <div>
                <h3>제목</h3>
                <ul>
                    <li><em>개봉일</em>{openDt}</li>
                    <li><em>제작상태</em>{moviePrdtStat}</li>
                    <li><em>영화구분</em>{movieType}</li>
                    <li><em>관람등급</em>{watchGradeNm}</li>
                    <li><em>상영시간</em>{showTm}</li>
                    <li><em>제작국가</em>{repNationCd}</li>
                    <li><em>감독</em>{director}</li>
                    <li><em>장르</em>{genre}</li>
                    <li><em>배급사</em>{dtNm}</li>
                </ul>
            </div>
            
        </div>
    );
};

export default MovieView;

⬇️Modal.js


import React from 'react';
import {AiOutlineCloseCircle} from 'react-icons/ai'

const Modal = ({onClose,movieInfo}) => {

    const {thumbUrl,movieNm,openDt,director,synop} = movieInfo

    return (
        <div className='modal'>
            <div className='bg'></div>
            <div className='popup'>
                <h3>{movieNm}</h3>
                <div>
                    <img src={thumbUrl} alt={movieNm}/>
                </div>
                <strong>감독: {director}</strong>
                <p>개봉일: {openDt}</p>
                <p>줄거리: {synop}</p>
                <p className='close' onClick={onClose}>
                    <AiOutlineCloseCircle/>
                </p>
            </div>
        </div>
    );
};

export default Modal;

✏️app - movie.json


아이콘 import해서 증감률 나타내기


결과

  • 흐린 배경: <Modal>

profile
어제보다 조금 더 성장하기!

0개의 댓글