Home 22/04/28/목 JavaScript심화, 스터디 프로젝트
Post
Cancel

22/04/28/목 JavaScript심화, 스터디 프로젝트

220428 Today I learned!

  • JavaScript 심화
  • 스터디 프로젝트
  • 백준 문제 풀이

1. Fact

(1) JavaScript 심화

어제 학습한 내용을 토대로 다양한 기능을 혼자 구현하며 학습했다.

  • 특정 버튼을 클릭하면 해당 페이지의 배경과 글자 색이 바뀐다.

    • 해당 버튼은 클릭하면 바디태그의 클래스가 변경된다. serAttribute
  • 욕설로 설정된 단어 리스트를 만들고 해당 단어를 input 창에 입력하면 *로 필터링 되어 보여준다.

    • 유저가 입력한 문자열을 변수에 저장한다.

    • 욕설 단어 리스트를 forEach를 통해 각 단어들을 replaceAll한다.

1
2
3
4
5
6
7
8
// badWords에 포함된 단어가 입력될 경우, '**'으로 변환하여 output에 출력한다.
function filterMessage(event) {
  let filteredInput = userInput.value;
  badWords.forEach((word) => {
  filteredInput = filteredInput.replaceAll(word, "**");
 });
  output.innerText = filteredInput;
}
  • input창에 데이터를 입력하고 해당 form을 submit을 하면 입력한 데이터에 대한 내용을 보여주는 카드컴포넌트를 새로 생성한다.
    • submit할 때 새로고침 되지 않기 위해 event.preventDefault();을 한다.
    • element 생성, innerText 변경, DOM 트리에 추가
  • 사용자가 입력한 내용을 기반으로 to-do 리스트를 만든다.
    • input 값이 비어있을 경우 submit을 하면 alert을 보여준다.
    • element 생성, innerText 변경, DOM 트리에 추가
  • 랜덤한 배경을 가지고 현재 시간을 보여준다.
    • lodash를 활용하여 랜덤으로 숫자를 뽑고 해당 이미지를 보여준다.
    • Date객체를 활용하여 현재 시간을 가져온다.
    • 만약 한자리 수면 앞에 0을 붙인다.
    • setInterval()함수를 통해 1초에 한번씩 시간을 보여주는 함수를 실행한다.
1
2
3
4
5
// 랜덤 배경

const bodyTag = document.querySelector("body");
const num = _.random(1, 6);
bodyTag.style.backgroundImage = `url('./images/${num}.jpg')`;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 시간을 보여주는 함수

const timeDiv = document.querySelector("#time");
const displayTime = function () {
  const now = new Date();
  const hours = now.getHours();
  const hoursDevide = hours % 12;
  const minutes = now.getMinutes();
  const seconds = now.getSeconds();

  const timeNow = hours < 12 ? "오전" : "오후";
  const hoursNow =
    hoursDevide.toString().length === 1 ? `0${hoursDevide}` : hoursDevide;
  const minutesNow =
    minutes.toString().length === 1 ? `0${minutes}` : minutes;
  const secondsNow =
    seconds.toString().length === 1 ? `0${seconds}` : seconds;
  timeDiv.innerHTML = `${timeNow} ${hoursNow} : ${minutesNow} : ${secondsNow}`;
};

(2) 스터디 프로젝트

  • 링피트 기록을 입력하는 모달창에서 받은 내용을 submit하면 해당 내용을 갖고 있는 카드 컴포넌트가 생성된다.
    • onChange 속성을 이용하여 input의 데이터를 기록
    • submit하는 순간 유저가 입력한 데이터를 리스트에 추가한다.
    • 리스트의 인덱스도 기록하여 해당 인덱스를 통해 데이터에 접근한다.
    • countList(인덱스), dateList(플레이한 날짜), timeList(플레이 시간), caloriesList(소모 칼로리)에 기록하여 데이터를 관리한다.
  • 카드 컴포넌트의 x를 누르면 해당 카드가 삭제된다.
    • 해당 카드의 count가 0이 된다. 0이된 인덱스는 카드로 표시를 하지 않는다.
  • 현재 구현 로직: 기록을 추가하는 버튼 클릭 => 모달창 => 링피트 플레이 내용 입력 => 제출 => 해당 내용을 보여주는 카드 컴포넌트 생성

  • props를 활용해서 데이터를 작성하다보니 이상한 구조가 되었다. 한번 전체적으로 수정해야할 것 같다. 😅
    • Index. js <= App.js <= Button.js <= Modal.js <= Card.js

(3) 백준 문제 풀이


2. Feeling

react에 대한 내용을 다 까먹었다고 생각했는데, 그래도 어떻게 하다보니 기능이 구현되고 내가 생각했던 것들이 진짜 웹사이트로 보이는 것 같아서 신기하다.

그런데 현재 큰 문제점이 있다. 우선 내일 프로젝트 중간 발표 이후에 다 수정을 해야 할 것 같다.

  • props를 활용해서 데이터를 작성하다보니 컴포넌트가 이상한 구조가 되었다.

    • Index. js <= App.js <= Button.js <= Modal.js <= Card.js

    • 위와 같이 단방향 구조를 가지게 되었다.

1
2
3
4
5
6
7
8
9
10
11
import Button from "./component/Button";
function App() {
  return (
    <div>
       {/*Button 컴포넌트의 자식으로 Modal컴포넌트가 있고 Modal컴포넌트의 자식으로 Card 컴포넌트가 있다.  */}
      <Button/>
    </div>
  );
}

export default App;


  • 유저가 입력한 데이터 항목에 따른 리스트를 갖고 있어서 데이터 관리가 불편하다. 한번에 모아서 객체 형식으로 저장을 해야 할 것 같다. (코드도 너무 길다… )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
function Modal({ show, hide }) {

  const [date, setDate] = useState("");
  const [time, setTime] = useState("");
  const [calories, setCalories] = useState("");
    
  {/* Card 컴포넌트에 보내줄 데이터 리스트들 */}
  const [count, setCount] = useState(0);
  const [dateList, setdateList] = useState([""])
  const [timeList, settimeList] = useState([""])
  const [caloriesList, setcaloriesList] = useState([""])

  {/* Card 컴포넌트에 보내줄 데이터 삭제 함수 */}
  {/* Card 컴포넌트에 보내줄 데이터 삭제 함수 실제로 데이터를 삭제하는 것이 아니라 인덱스를 0으로 바꿔주고 0은 카드 컴포넌트로 생성하지 않는다. */}  
  const deleteCard = (num) => {
    const countList = [...count];
    countList[num] = 0;
    setCount(countList);
  };

  {/* 사용자가 인풋 데이터를 입력하면 해당 내용을 저장한다.  */}
  const changeDate = (event) => {
    setDate(event.target.value);
  };
  const changeTime = (event) => {
    setTime(event.target.value);
  };

  const changeCalories = (event) => {
    setCalories(event.target.value);
  };


  {/* 제출 했을 때 발생하는 함수 */}
  const formSubmit = (event) => {
    hide();
    event.preventDefault();

   {/*현재 유저가 입력한 데이터를 리스트에 추가한다. */}
    const dateArr = [...dateList];
    const timeArr = [...timeList];
    const caloriesArr = [...caloriesList];
    dateArr.push(date);
    timeArr.push(time);
    caloriesArr.push(calories);   
    setdateList(dateArr);
    settimeList(timeArr);
    setcaloriesList(caloriesArr);

    const countList = [...count];
    let lastCount = countList.length;
    countList.push(lastCount);
    setCount(countList);

    setDate("");
    setTime("");
    setCalories("");
  };

  return (
    <div>
      <Card
        count={count}
        date={dateList}
        time={timeList}
        calories={caloriesList}
        deleteCard={deleteCard}
      ></Card>
		{/*... 생략  */}
    </div>
  );
}


  • 새로고침을 하면 데이터가 다 삭제된다. 로컬스토리지를 활용해야할 것 같다.


3. Finding

잊고 있었던 리액트 기초!

  • JS 문법은 {}를 써야한다. props도 {}안에 써야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import PropTypes from "prop-types";
import styled from "styled-components";

function Card({ count, date, time, calories, deleteCard }) {
  return (
    <div>
      <StyledDiv>
        <StyledCardContainer>
          {count.map((i) =>
            i === 0 ? null : (
            <StyledCard key={i}>
              <StyledP1>{date[i]} </StyledP1>
              <StyledDeleteButton onClick={() => deleteCard(i)}></StyledDeleteButton>
              <StyledP2>{calories[i]} kcal</StyledP2>
              <StyledP3>{time[i]} </StyledP3>            
            </StyledCard>)
          )}
        </StyledCardContainer>
      </StyledDiv>
    </div>
  );
}


  • 컴포넌트를 중복 render하면 안된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import Button from "./component/Button";
import Modal from "./component/Modal";
import Card from "./component/Card";


function App() {
  return (
    <div>
      {/* Button 컴포넌트의 자식으로 Modal컴포넌트가 있고 Modal컴포넌트의 자식으로 Card 컴포넌트가 있다. */}
      {/* 따라서 Card 컴포넌트와 Modal 컴포넌트는 작성하면 안된다. */}
      <Card />
      <Modal />
      <Button />
    </div>
  );
}

export default App;


4. Future Action & Feedback

Future Action진행 상황Feedback
DOM을 깨우치다pause 🤦‍♀️잠시 중단!
강의에서 학습한 flex-website 혼자 제작하기in progress 🚀현재 Section2까지 진행한 상태이다.
오는 주에 Section3를 할 예정이다.
1일 1알고! 🔥in progress 🚀 


This post is licensed under CC BY 4.0 by the author.