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 트리에 추가
- submit할 때 새로고침 되지 않기 위해
- 사용자가 입력한 내용을 기반으로 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) 백준 문제 풀이
- 1916 최소 비용 구하기
- 문제풀이
- 그래프
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 🚀 |