4주차 - 프로그래스바 달기 + 화살표 함수 {}
본문 바로가기
항해 중/4주차 리액트 숙련반

4주차 - 프로그래스바 달기 + 화살표 함수 {}

by 은돌1113 2021. 11. 22.

- 버킷리스트에 프로그래스바 달기!

 

1) 상태값 형태를 변경한다.

: Redux에 기본값을 딕셔너리로 만들어서, 버킷리스트 텍스트와 완료 여부를 넣습니다.

const initialState = { // 초기값 설정
    list : [
        {text : "영화관 가기", completed : false},
        {text : "매일 책읽기", completed : false},
        {text : "수영 배우기", completed : false},
    ]
    // ["영화관 가기", "매일 책읽기", "수영 배우기"]
}

 

2) 완료하기 버튼 추가

: 완료 버튼을 닫고, 버킷 모듈에서도 완료 여부를 추가 해줍니다.

// Detail.js

  const successBucketList = ()=>{

    console.log("액션을 생성 할꺼야!");
    dispatch(updateBucket(bucketIndex));
    history.goBack(); // 완료 후에는 뒤로가기를 해서 버킷리스트 목록을 보여준다.
  }

return (
    <div>
      <h1>{bucketList[bucketIndex].text}</h1>
      <button onClick={deleteBucketList}>삭제하기</button>
      <button onClick={successBucketList}>완료하기</button>
      <button onClick={()=>{history.goBack()}}>뒤로가기</button>
    </div>
  )
// bucket.js

const UPDATE = 'bucket/UPDATE'; // 완료하기 기능

export function updateBucket(bucketIndex){ // UPDATE Action에 대한 액션 객체
    
    return {
        type : UPDATE,
        bucketIndex
    };
}

// reducer
export default function reducer(state = initialState, action = {}) {
                                // state = {} -> 기본값(초깃값)을 준다.
    switch (action.type) {

        case 'bucket/DELETE': {
            console.log("이제 값을 삭제 할꺼야!");
            const new_bucket_list = state.list.filter((data, index)=>{
            // state는 딕셔너리 형태이고 state 안에 list가 배열 형태로 있기 때문에

                return index != action.bucket
            })

            return {list : new_bucket_list};
        }

        // do reducer stuff
        default:
            return state;
    }
}

 

3) 완료하면 색을 바꿔준다.

: 완료한 리스트의 색상을 변경 해줍니다.

// BucketList.js

const ItemStyle = styled.div`
  padding: 16px;
  margin: 8px;
  background-color: ${(props)=> props.completed ? "orange" : "aliceblue"};
`;

 

4) Progress 컴포넌트를 만들어 줍니다.

// App.js

import React from "react";
import styled from "styled-components";
import { Route, Switch } from "react-router-dom";
import NotFound from "./NotFound";

import { useDispatch } from "react-redux";
// Store에 있는 값을 수정하기 위해서 import
import { createBucket } from './redux/modules/bucket';

// BucketList 컴포넌트를 import 해옵니다.
// import [컴포넌트 명] from [컴포넌트가 있는 파일경로];
import BucketList from "./BucketList";
import Detail from "./Detail";
import Progress from "./Progress";


function App() {

  const text = React.useRef(null);

  const dispatch = useDispatch();

  const addBucketList = () => {

    if (text.current.value !== "") {
      dispatch(createBucket(text.current.value));
      text.current.value = "";
    } else {
      alert("추가 할 버킷리스트를 작성 해주세요")
    }
  }

  return (
    <div className="App">
      <Container>
        <Title>내 버킷리스트</Title>
        <Progress></Progress>
        <Line />
        {/* 컴포넌트를 넣어줍니다. */}
        {/* <컴포넌트 명 [props 명]={넘겨줄 것(리스트, 문자열, 숫자, ...)}/> */}
        <Switch>
          <Route path="/" exact
            render={(props) => (
              <BucketList />
            )}
          />
          <Route path="/detail/:index" component={Detail} />
          <Route>
            <NotFound></NotFound>
          </Route>
        </Switch>
      </Container>

      {/* 인풋박스와 추가하기 버튼을 넣어줬어요. */}
      <Input>
        <input type="text" ref={text} />
        <button onClick={addBucketList}>추가하기</button>
      </Input>
    </div>
  );
}

const Input = styled.div`
  max-width: 350px;
  min-height: 10vh;
  background-color: #fff;
  padding: 16px;
  margin: 20px auto;
  border-radius: 5px;
  border: 1px solid #ddd;
`;

const Container = styled.div`
  max-width: 350px;
  min-height: 60vh;
  background-color: #fff;
  padding: 16px;
  margin: 20px auto;
  border-radius: 5px;
  border: 1px solid #ddd;
`;

const Title = styled.h1`
  color: slateblue;
  text-align: center;
`;

const Line = styled.hr`
  margin: 16px 0px;
  border: 1px dotted #ddd;
`;

export default App;
// Progress.js

import React from 'react';
import styled from 'styled-components';
import { useSelector } from 'react-redux';

const Progress = (props) => {

    const bucket_list = useSelector((state) => state.bucket.list)

    let count = 0;
    bucket_list.map((item) => {
        if (item.completed === true) {
            count++;
        }
    })

    // let count = bucket_list.filter((item) => {
    //     if (item.completed === true) {
    //         return item
    //     }
    // }).length

    return (
        <ProgressBar>
            <HighLight width={Math.round((count / bucket_list.length) * 100) + "%"}>
            {/* -> Math.round(완료 개수 / 전체 * 100) */}
            </HighLight>
        </ProgressBar>
    );
}

const ProgressBar = styled.div`
    background-color: #eee;
    width: 100%;
    height: 40px;
`

const HighLight = styled.div`
    background-color: orange;
    transition : 1s;
    // == transition : 1s width;
    width: ${(props)=> props.width};
    height: 40px;
`

export default Progress;

Q.. 화살표 함수(Arrow Function) 사용 시 {}은 어떨 때 사용하는 가?

A. {}를 사용하면 return을 적어줘야 한다. + 구문이 하나일 경우 생략 가능 + 객체를 사용 할 때는 ()로 감싸준다.

background-color: ${(props)=> {props.completed ? "orange" : "aliceblue"}};

-> 이렇게 작성하면 오류가 발생한다. (Failed to compile)

background-color: ${(props)=> {return props.completed ? "orange" : "aliceblue"}};

-> 팀원들께 여쭤보니 arrow function에서 {}를 사용하면 return을 적어야 한다고 알려주셔서 return을 붙여보니 좋았다!

background-color: ${(props)=> props.completed ? "orange" : "aliceblue"};

-> 구문이 하나일 때는 {}를 생략 해도 된다. 

background-color: ${(props)=> (props.completed ? "orange" : "aliceblue")};

-> 중요한 점은 객체를 사용 할 때는 ()를 묶어 줘야 한다는 점이다.

객체가 한 개일 때는 오류가 발생하지 않지만 여러개의 객체를 사용 할 경우 오류가 발생한다!

댓글