학습내용
- 프로그래머스
- OX 퀴즈
- 리액트
- Redux
- React-router-dom
문제 설명
덧셈, 뺄셈 수식들이 'X [연산자] Y = Z' 형태로 들어있는 문자열 배열 quiz가 매개변수로 주어집니다. 수식이 옳다면 "O"를 틀리다면 "X"를 순서대로 담은 배열을 return하도록 solution 함수를 완성해주세요.제한사항
연산 기호와 숫자 사이는 항상 하나의 공백이 존재합니다. 단 음수를 표시하는 마이너스 기호와 숫자 사이에는 공백이 존재하지 않습니다.
1 ≤ quiz의 길이 ≤ 10
X, Y, Z는 각각 0부터 9까지 숫자로 이루어진 정수를 의미하며, 각 숫자의 맨 앞에 마이너스 기호가 하나 있을 수 있고 이는 음수를 의미합니다.
X, Y, Z는 0을 제외하고는 0으로 시작하지 않습니다.
-10,000 ≤ X, Y ≤ 10,000
-20,000 ≤ Z ≤ 20,000
[연산자]는 + 와 - 중 하나입니다.입출력 예
quiz result ["3 - 4 = -3", "5 + 6 = 11"] ["X", "O"] ["19 - 6 = 13", "5 + 66 = 71", "5 - 15 = 63", "3 - 1 = 2"] ["O", "O", "X", "O"]
풀이
function solution(quiz) {
let result = [];
for(i of quiz){
const calculation = i.split("=")[0]
const answer = i.split("=")[1]
result.push(eval(calculation) === Number(answer) ? "O" : "X")
}
return result;
}
result
생성quiz
를 돌면서 연산 일치 여부 확인split()
메서드로 문제와 답을 분리해서 calculation
, answer
변수로 할당eval()
함수로 calcultaion
을 계산한 답과 answer
가 일치하면 result
에 "O"
를, 불일치하면 "X"
를 추가
eval()
문자로 표현된 자바스크립트 코드를 실행하는 함수로 매개변수는 문자열만 가능하다. 단, caller의 권한으로 수행한다는 특성상 악의적인 코드가 실행될 수 있으므로 절대 사용하지 않는다.📌 참조문헌
문자열을 바로 연산할 수 있는 방법을 강구하다가 eval()
함수로 풀었는데, Mdn 문서를 읽어보니 나쁜 코드의 예제가 딱 내가 풀이한 방법과 같다.... ㅇㅋ..안쓸게...
전역 상태 관리 라이브러리로 중앙 state 관리소를 통해 state를 생성하고 관리한다.
useState
는 props drilling 이슈로 인해 관리가 어렵다는 단점이 있는데 redux를 사용하면 이런 이슈로부터 자유롭다.설치 명령어
yarn add redux react-redux
useState
를 사용해서 생성한 state폴더 구조
모듈을 생성할 때는 크게 action type, action creator, initial state, reducer 등 같은 기능끼리 분류하는데 이를 덕스(Ducks) 구조라고 한다.
action type
리듀서로 보내는 명령. 이곳에서 생성된 명령은 이후 action creator에서 사용되고 리듀서로 전달된다. value
는 대문자여야만 한다.
action creator
액션 객체를 반환하는 함수. 컴포넌트에서 사용할 예정이므로 export
가 필요하다.
장점
- 휴먼에러(오타) 방지
- 효율적인 유지보수 가능
- 코드 가독성 증가
initial state
state의 초기값. 객체, 배열, 원시데이터 등 다양한 형태의 데이터 가능.
reducer
dispatch
를 통해 전달받은 액션 객체 검사 후, 조건 일치시 새로운 상태값 생성. 즉, 변화를 일으키는 함수.
configStore.js
import counter from "../modules/counter";
const rootReducer = combineReducers({
counter: counter,
});
App.jsx
import { useDispatch, useSelector } from "react-redux";
import { minusOne, plusOne } from "./redux/modules/counter";
const App = () => {
const dispatch = useDispatch();
const number = useSelector((state) => state.counter.number);
return (
<div>
{number}
<button
onClick={() => {
dispatch(plusOne());
}}
>
+ 1
</button>
<button
onClick={() => {
dispatch(minusOne());
}}
>
- 1
</button>
</div>
);
};
모듈 연결
생성한 모듈(counter.js)은 configStore.js에 연결
컴포넌트에서 스토어 조회
react-redux
에서 제공하는 useSelector
훅을 사용해서 스토어에 접근
컴포넌트에서 action creator 사용
action creator를 import
후 useDispatch()
에 action creator 삽입
useDispatch()
액션 객체를 리듀서로 보내는 스토어 내장함수로 액션을 발생시킨다. 함수 자체로 사용하기보다는 주로dispatch
에 할당해서dispatch(action)
형태로 쓰인다.
페이지를 구현해주는 패키지
설치 명령어yarn add react-router-dom
useNavigate()
특정 버튼이나 컴포넌트 클릭시 페이지로 즉시 이동
<Link>
훅은 아니지만useNavigate()
와 비슷한 기능이다. 정확히는 JSX에서<a>
태그를 대체하는 API.<a>
태그는 페이지를 이동하는 과정에서 재렌더링이 되기 때문에 redux나useState
를 통해 메모리상에 구축해놓은 상태값이 초기화 된다. 즉, 성능면에서 효율적이지 못하다.
useLocation()
현재 페이지의 정보를 가져오는 훅. 해당 정보를 통해 페이지 안에서 조건부 렌더링과 같은 용도로 활용 가능.
useParams()
URL의 query string을 가져오는 훅. 주로 상품페이지처럼 같은 레이아웃을 사용하지만 내용만 다른 페이지를 구현할 때 사용한다.
query string
https://www.vlive.tv/post/1-30241242에서post/
뒤에 해당하는 값
📌 useParams를 통한 라우팅 참조
path
에 유동적인 값을 지정해 특정 페이지로 이동하는 방식으로 동적 라우팅이라고도 한다.
Works.js
const Works = () => {
return <div>Works</div>;
};
Router.js
const Router = () => {
return (
<BrowserRouter>
<Routes>
<Route path="works/:id" element={<Works />} />
</Routes>
</BrowserRouter>
);
};
:id
= 동적값으로 works/
뒤에 어떤 값이 오든 Work 컴포넌트로 이동한다.
심화주차 끝~!은 아니고 아직 과제가 남았다. 이번주는 과제 뚝딱 헤치우고 개인프로젝트 꼭 시작해야지😎