코더
react 기본 + react 영단어 만들기 본문
--------------------------------react 기본----------------------------------------------
react 설치
npx create-react-app voca(npx => npm에 올라가있는 패키지를 바로 실행시켜준다)
npm start : 프로젝트 시작(띄운다)
(터미널에서)ctrl + c => 프로젝트를 내린다.
document.getElementById('root'); => index.html의 <div id = "root"></div>에 <APP />을 렌더링시켜준다.
jsx => javascript내부에 html처럼 작성하는 것
eject => 내부 설정파일을 꺼내는 역할을 한다.(웹페이지나,바벨설정 바꿀때 사용가능)
HMR => 개발 중에 모듈의 변경 사항을 즉시 적용
{} => 중괄호로 숫자나 문자열을 가져 올 수 있다.(boolean or 객체는 표현하지 못한다.)
- / : 루트
- ./ : 현재 위치
- ../ : 현재 위치의 상단 폴더
./ => 현재 디렉토리를 나타내는 상대 경로이다.(바로 가져 올 수 있다 만약 아닐 시 상위폴더 가져와야함)
구조분해 할당 예시 :
let {name, age} = user;
let name = user.name;
let age = user.age;
1.컴포넌트
app컴퍼넌트는 함수로 만들어져있고 이 app컴포넌트는 export default => index.js에서 import App from "./App";되어 사용된다
(내보낸 항목은 기본적으로 default로 가져오며, 해당 항목을 가져올 때 이름을 지정하지 않고 가져와서 사용할 수 있다.)
위와 같은 예시는 다음예시에서도 적용이된다
위의 app.js에서는 hello와 welcome 컴포넌트를 임폴트 해주고 hello에서는 welcome과 world를 임포트 해준다.
Hello
welcome jun11 ==> 결과값
world kim
welcome jun11
JSX는 하나의 태그만 사용가능하기 때문에 <div>태그로 <Hello />태그를 감싸주었다.
<Hello />태그는 안에 들어가는 내용이 없을 때 셀프클로즈 역할 해준다.
2.css
react는 인라인 스타일(html요소에 직접 스타일 속성을 지정)로 작성할때 객체 형태로 작성해야하면 camelCase(첫번째는 소문자 두번째 단어는 대문자)로 작성해야 한다.
ex)
<div style={{ color: "red", fontSize: "20px" }}>Hello World</div>
<div style = "color : red; font-size: 20px">Hello Worlc</div>
module.css파일을 이용하는 방법
App.css에 바로 .box를 만들고 Hello.css에 바로 .box를 만들면 오버라이딩이 되어 header부분에 코드가 들어가기 때문에 원하는 결과값이 나오지 않는다. 즉, App.module.css와 Hello.module.css를 만들어 준 후
두 코드를 App.js,Hello.js에 넣은후
이렇게 코드를 넣으면 각 컴포넌트에 .box가 할당되는것을 알 수 있다.
===>Hello.js의 코드
3.이벤트 처리
event처리 하는방법
-1. 미리함수를 만들어 놓고 전달
-2.내부에서 직접 함수를 작성
4.state
useState를 사용해서 상태값을 관리해준다.
import { userState } from "react";를 맨 첫번째 줄에 적어준다.
useState는 배열을 반환한다.
const [변수명,setName] = useSTate('초기값');
((변수명은 state이고 setNam은는 state를 변경해주는 함수이다.))
react에서 사용 할 코드
자바스크립트라면 사용 할 코드
Props
-React에서 컴포넌트에 전달되는 데이터를 의미하는 객체
이 코드에서 Hello(props) 는 Hello({age})로 대체할 수 있다.
이 것 또한 구조분해 할당인데 예를 들어 const props = { age:30, name:”Mike”}; 라는값을 const age = props.age; const name = props.name이로 변수 할당을 할 수 있는데 이것을 const {age, name } = props 라고 구조분해할당 될 수 있기 때문이다. (즉, ({age}) 는 (props)라고 볼 수 있다.) 그럼 이 props.age는Hello.js파일에서의 age 즉, 가져오는 age값이 아닌 이 파일에서 만들어진 age값이라고 볼 수 있다.====> 너무 헷갈리면 뒤에있는 변수를 추출해서 구조분해 할당을 만든다 생각하자.
이런 식으로 한 컴포넌트가 가지고 있는 state를 props가 넘길 수 있다.( name은 이 컴포넌트에서는 state이지만 저 입장에서는 props이다. )
-------------------------------------react 영단어 만들기------------------------------------
react 영단어 만들기
1.map()함수
-map()함수는 배열을 받아서 또 다른 배열을 반환하는 함수이다.
dummy.days.map(day => ())는 매개변수가 하나이기 때문에 dummy.days.map((day) => ()) 와 같고
map 함수는 반드시 괄호를 동반한다.
data.json 파일 만들어 준후 day.js,daylist.js,header.js 파일은 새로운 app.js에 import 시켜준다.
2.react-router-dom 라우터 구현
npm install react-router-dom을 실행 한다.
<import BrowswerRouter, Route, Routes } from "react-router-dom"; 을 통해 import해준다.
return문 다음에 바로 BrowserRouter 로 감싸준다.
switch 대신 element = {<DayList /> } 와 같이 element를 사용하여 정확한 결과를 보여주게 되었다.
<Route path ="/day/:day" 에서 : day는 day라고 키로들어오는데 이 키의 값을 얻기위해서는
import { userParams } from "react-router-dom"을 사용한다.
ex) 실제 이 :day에 무슨 값이 들어왔는지 알기위해서
const a = useParams();
console.log(a);
라고 하면 값이 키와 값이 {day : "2"}와 값이 찍히는 모습을 볼 수 있다.
"/*"는 원하는 링크로 접속하지 못하였을때 사용하면 된다. 그 후 ElementPage에 <Link to="/">돌아가기</Link>를 추가해서 돌아가기 버튼을 클릭하면 다시 처음 페이지 링크로 가는 코드를 만들었다.
3. useState
useState는 React 함수형 컴포넌트에서 상태(state)를 추가하고 관리하는 데 사용된다.
count [상태값, 상태값을 변경] = 초기값; 으로 구성된다 count[상태값, 상태값을 변경] = useState(file);
아래는 useState로 증가 감소를 나타내는 예시이다.
ex)
import React, { useState } from 'react';
function Counter() {
// useState를 사용하여 초기값 0인 count 상태를 생성합니다.
const [count, setCount] = useState(0);
// 버튼 클릭 시 count 값을 증가시키는 함수
const increment = () => {
setCount(count + 1);
};
// 버튼 클릭 시 count 값을 감소시키는 함수
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<h1>Counter</h1>
<p>Count: {count}</p>
<button onClick={increment}>증가</button>
<button onClick={decrement}>감소</button>
</div>
);
}
export default Counter;
useState(false);를 초기값으로 설정을 해((뜻을 숨기는 상태이다.)) !isShow를 클릭 할 시 !isShow 즉 true값을 반환한다.
Day.js 파일에서 Word 컴포넌트를 사용할 때 전달하는 war props는 해당 파일에서는 변수로 간주된다.(word를 코드에서 구별하기 위해 war로 바꾸었음) 그러나 전체적인 관점에서 보면 Day.js 파일에서 전체적으로는 Word 컴포넌트에 전달되는 props 중 하나이다
즉, Day.js 파일에서 Word 컴포넌트에게 전달되는 props 중 하나인 war는 해당 파일에서는 변수처럼 다루지만, 전체적인 관점에서는 Word 컴포넌트에게 전달되는 props의 일부분이다.
json server설치
npm install -g json-server
json-server --watch ./src/db/data.json --port 3001
4.useEffect
어떤 상태값이 바뀌었을 때 동작하는 함수를 작성 할 수 있다.(함수가 호출된 타이밍은 렌더링결과가 실제 DOM에 반영된 직후이다.)
의존성 배열
useEffect 훅에 입력하는 두번째 매개변수(변경 될 때만 이 함수가 실행된다.) => 딱한번만 실행하려면 [] 빈배열을 전달한다.
fetch
- fetch 요청이 http://localhost:3001/words?day=${day}에 보내진다.
- 서버가 응답을 보내고, 이 응답이 JSON 형식으로 변환된다.
- 변환된 JSON 데이터가 data 변수에 할당됩니다.
- data 변수를 setWords(data)를 통해 words 상태로 설정하여, 이 상태를 기반으로 컴포넌트가 다시 렌더링 된다.( 즉, 기존에 import dummy ~~ 해서 dummy.words.map을 할 필요없이 이미 words가 json파일의 days나 day에 따른 word를 반환하기 때문에 바로 words.map을 사용 할 수 있고 import dummy 같은 코드도 필요가 없어진것이다.
day.js
DayList.js
5.useFetch
useFetch(url)을 통해 useEffect를 통해 const words = useFetch(`http://localhost:3001/words?day=${day}`)
로 day.js파일을 받았고
위와 같이 DayList.js에서는 http://localhost:3001:days를 통해 useFetch(url)의 함수를 받고 fetch(url)에서 주소를 받은 후 받은 값은 data에 return으로 받아준 후 days로 return된 data 값을 받아준다.
6,Put,Delete
==> Put 사용
body : { 는 수정을 위한 정보를 실어서 보내준다.
...war은 war 객체의 기존 속성들을 포함한다.
==> DELETE를 method로 지정해준 후 id 값이 0일때 삭제를 return null을 통해 삭제해준다. 당연히 <button onClick={del}을 추가해준다.
7.useRef
- input창에 적힌값을 알기위해 useRef 훅을 사용한다. => DOM에 접근 할 수 있게해준다.
import { useRef } from "react";
DOM
- 가상 DOM: React가 상태나 속성 변경 시 메모리 내에서 유지하는 DOM의 사본이다. 가상 DOM은 실제 DOM을 효율적으로 업데이트하기 위해 사용된다. console.log로 출력되는 값은 가상 DOM의 상태를 나타낸다.
- 실제 DOM: 웹 브라우저가 렌더링하는 실제 HTML 요소들이다. 이는 사용자가 화면에서 보는 내용입니다. 실제 DOM 조작은 브라우저에서 직접 이루어지며, 가상 DOM을 통해 최소화한다
따라서, 가상 DOM은 console.log에 찍히는 값과 관련이 있으며, 실제 DOM은 화면에 표시되는 내용을 의미한다. React는 가상 DOM을 사용하여 변경 사항을 추적하고, 필요한 부분만 실제 DOM에 반영함으로써 성능을 최적화한다.
useNavigate
-주소를 입력하면 해당 페이지로 이동을 한다.
import {useNavigate} from "react-router-dom";
const navigate = useNavigate();
if (res.ok) {navigate(`/day/${dayRef.current.value}`)
}을 사용한다.
CreateWord.js
CreateDay.js
-------------------------------------------오류 해결------------------------------------------
1.
기존의 react 버전에서는 switch를 사용하여 Route exact path 를 통해 경로를 특정해 주었는데 이제는 element가 직접 받게 되어서
기존의 <import BrowswerRouter, Route, Switch } from "react-router-dom"; 에서 <import BrowswerRouter, Route, Routes } from "react-router-dom"; 로 바꿔주었다 기존에 문법을 배울때에도 경로를 특정해주려 exact를 쓰는게 불편했는데 훨씬 간소화가 되어 좀 더 사용하기 편해진거 같다
function App() {
return (
<div className="App">
<Header />
<BrowserRouter>
<Routes>
<Route path="/" element={<DayList />} />
<Route path="/day/:day" element={<Day />} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
기존의 이 코드가 오류가 계속 나서 생각을 해보니 Header태그 또한 BrowserRouter에 영향을 받는다는 것을 깨닫고 아래와 같이 고쳐주었다
잘 돌아갔다
2. 역시나 EmptyPage를 사용하기 위해서 /*를 사용해야 하는것을 찾기까지 좀 시간이 많이 걸렸다.(이것 또한 switch가 사용되지 않기 때문이라 생각한다.)
3.json server 설치 과정중에 npm install -g json-server 에서 오류가 발생해 sudo npm install -g json-server 로 해결해주었다.(올바른 해결방법인지는 x)
4. react로 4일동안 계속고민하던 문제가 생겼었는데 너무 간단하게 해결이 되었다. 처음에 json-server --watch ./src/db/data.json --port 3001을 json파일을 설치하면서 zsh파일에 생성해주었는데 작업중인 콘솔작업에서 일을 하지않고 새로운 환경에서 작업을 해주던게 오류가 겹쳐 아예 정보가 넘어가지 않았다.