vscode 확장 패키지 추가
1. - Auto Import - ES6, TS, JSX, TSX
2. - Reactjs code snippets
3. - ESLint
4. - Prettier - Code formatter
App.css
.hello{ color: red; } .box-style{ color: rgb(64, 159, 116); }
App.js
import logo from './logo.svg'; import "./App.css"; //0.React 엔진 - 데이터변경감지에서UI 그려주는 ! //1.실행과정(index.html) SPA //2.JSX문법 //3.바벨(자바스크립트 ES5)->ES6 //(1) retrun 시에 하나의 Dom 만 리턴할 수 있다. //(2) 변수선언은 let 혹은 const 로만 해야 함. //(3) if 사용 불가능 -> 삼항연산자 (조건 ? 값(true) : 값 (false)) //(4) 조건부 렌더링 (조건 && 값 true) //(5) css 디자인 // - 내부에 적는 방법 //- 외부 파일에 적는 방법 //- 라이브러리 사용 (부트스트랩, component-sytled) let a = 10; let b = 20; function App() { let c; let d = undefined; console.log(2, c, d); // const myStyle = { // color: "red" // }; return
해딩태그 {b === 20 && '20입니다.'}
; } export default App;
4강 - 배열(map, filter, slice, concat, spread연산자)
1)test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width= , initial-scale=1.0"> <title>Document</title> </head> <body> <script> //concat,filter, map, slice, 스프레드(전개) 연산자 console.log("1.========== 스프레드 연산자"); const a=[1,2,3]; const b =[...a]; b.push(4);//b 의 데이터 변경 console.log(`a의 값은 : ${a}`) ; //1,2,3 console.log(`b의 값은 : ${b}`) ; //1,2,3,4 console.log("\n\n2.========== 추가하기"); const a2=[1,2,3]; const b2=a2.concat(4); console.log(`a2의 값은 : ${a2}`) ;//1,2,3 console.log(`b2의 값은 : ${b2}`); //1,2,3,4 const c2=[0,...a2, 4]; console.log(c2); //0,1,2,3,4 console.log("\n\n3.========== 걸러내기"); //삭제하기 const a3 =[1,2,3]; const d3=a3.filter((n)=>{return n!=1;}); // bool 을 return 받는다. console.log(d3); //2,3 console.log("\n\n4.========== 잘라내기"); //잘라내기 const a4=[1,2,3] const b4=a4.slice(0,2); console.log(b4); //1,2 const c4=[...a4.slice(0,2)]; console.log(c4); //[Array(2)] [[1,2]] console.log("\n\n5.========== 반복하기"); //반복하기 const a5=[1,2,3] // for(let i=0; i<a5.length; i++){ // console.log(a[i]); // } a5.forEach((item)=>{ console.log(item); //리턴 못함. }); const b5=a5.map((n)=>n); console.log(b5); //1,2,3 const b5 =[...a5]; const c5=a5.map((n)=>n+10); //map 은 개별적으로 가공이 가능하다. console.log(c5); //1,2,3 const b5 =[...a5]; </script> </body> </html>
2.App.js
import logo from './logo.svg'; import "./App.css"; import Wood from './wood'; //0.React 엔진 - 데이터변경감지에서UI 그려주는 ! //1.실행과정(index.html) SPA //2.JSX문법 //3.바벨(자바스크립트 ES5)->ES6 //(1) retrun 시에 하나의 Dom 만 리턴할 수 있다. //(2) 변수선언은 let 혹은 const 로만 해야 함. //(3) if 사용 불가능 -> 삼항연산자 (조건 ? 값(true) : 값 (false)) //(4) 조건부 렌더링 (조건 && 값 true) //(5) css 디자인 // - 내부에 적는 방법 //- 외부 파일에 적는 방법 //- 라이브러리 사용 (부트스트랩, component-sytled) function App() { let list = [1, 2, 3]; return ( <div> <div> {list.map(function (n) { return <h1>{n}</h1>; })} </div> </div> ) ; } export default App;
5.concat,filter, map, slice, 스프레드(전개) 연산자
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width= , initial-scale=1.0"> <title>Document</title> </head> <body> <script> //concat,filter, map, slice, 스프레드(전개) 연산자 console.log("1.========== 스프레드 연산자"); const a=[1,2,3]; const b =[...a]; b.push(4);//b 의 데이터 변경 console.log(`a의 값은 : ${a}`) ; //1,2,3 console.log(`b의 값은 : ${b}`) ; //1,2,3,4 console.log("\n\n2.========== 추가하기"); const a2=[1,2,3]; const b2=a2.concat(4); console.log(`a2의 값은 : ${a2}`) ;//1,2,3 console.log(`b2의 값은 : ${b2}`); //1,2,3,4 const c2=[0,...a2, 4]; console.log(c2); //0,1,2,3,4 console.log("\n\n3.========== 걸러내기"); //삭제하기 const a3 =[1,2,3]; const d3=a3.filter((n)=>{return n!=1;}); // bool 을 return 받는다. console.log(d3); //2,3 console.log("\n\n4.========== 잘라내기"); //잘라내기 const a4=[1,2,3] const b4=a4.slice(0,2); console.log(b4); //1,2 const c4=[...a4.slice(0,2)]; console.log(c4); //[Array(2)] [[1,2]] console.log("\n\n5.========== 반복하기"); //반복하기 const a5=[1,2,3] // for(let i=0; i<a5.length; i++){ // console.log(a[i]); // } a5.forEach((item)=>{ console.log(item); //리턴 못함. }); const b5=a5.map((n)=>n); console.log(b5); //1,2,3 const b5 =[...a5]; const c5=a5.map((n)=>n+10); //map 은 개별적으로 가공이 가능하다. console.log(c5); //1,2,3 const b5 =[...a5]; const data={phone:"222"} const a6={id:1, name:"홍길동",phone:"1111"}; const b6={...a6, name:"임꺽정"} const c6={...data, ...b6}; console.log("b6 : ",b6); console.log("c6 : ",c6); const users=[ {id:1, name:"구태모",phone:"222"}, {id:2, name:"이대엽",phone:"333"}, {id:3, name:"이대엽",phone:"444"}, ]; const updateUserDto={ id:2, name:"홍길동" }; users[1].name=updateUserDto.name; console.log(users); const newUser =users.map(u=> u.id ===updateUserDto.id?{...updateUserDto}:u); console.log("newUser " ,newUser); </script> </body> </html>
6.useState
import { useState } from "react"; import "./App.css"; function App() { const [num, setNum] = useState(5); console.log("App 실행됨") const sample = [ { id: 1, name: "홍길동" }, { id: 2, name: "임꺽정" }, { id: 3, name: "장보고" }, { id: 4, name: "코스" }, ]; const [users, setUsers] = useState(sample);// 레퍼런스가 변경되야 동작!! const download = () => { setUsers([...sample, { id: num, name: "조자룡" }]); setNum(num + 1) }; //랜더링 시점= 상태값 변경 return ( <div> <button onClick={download}>다운로드</button> {users.map(u => <h1>{u.id} : {u.name}</h1> )} </div > ) ; } export default App;
7.useEffect
import { useEffect, useState } from "react"; import "./App.css"; //map, filter, concat, spread, slice function App() { const [data, setData] = useState(0); const [search, setSearch] = useState(0); const download = () => { //다운로드 받고 (통신) let downloadData = 5; //가정 setData(downloadData); } //useEffect 실행시점 : //(1) App() 함수가 최초실행 될때(마운트 될 때) App 그림이 최초 그려질때 //(2) 상태 변수가 변경될 때( dependencyList 에 등록되어 있어야 함) //(3) 의존리스트 관리를 할 수 있다. useEffect(() => { console.log("userEffect 실행됨"); download(); }, [search]); return ( <div> <button onClick={() => { setSearch(2); }}>검색</button> <h1>데이터 : {data}</h1> <button onClick={() => { setData(data + 1) }}>더하기</button> </div> ); } export default App;
8. useMemo
import { useMemo, useState } from "react"; import "./App.css"; //useMemo => 메모라이제이션(기억) function App() { const [list, setList] = useState([1, 2, 3, 4]); const [str, setStr] = useState("합계") const getAddResult = () => { //1초 let sum = 0; list.forEach(i => sum = sum + i); console.log("sum ", sum); return sum; } const addResult = useMemo(() => getAddResult(), [list]); return (<div> <button onClick={() => { setStr('안녕') }}>문자변경</button> <button onClick={() => { setList([...list, 10]); }}>리스트값 추가</button> <div> {list.map(i => <h1>{i}</h1>)} </div> <div>{str} : {addResult}</div> </div>); } export default App;
9.useRef
10. components styled
styled-components 설치
https://styled-components.com/
App.js
import './App.css' import LoginPage from './pages/LoginPage'; function App() { return ( <div> <LoginPage /> </div > ); } export default App;
LoginPage.js
import React from 'react'; import Footer from '../components/Footer'; import Header from '../components/Header'; import Login from '../components/login/Login'; const LoginPage = () => { return ( <div> <Header /> <Login /> <Footer /> </div> ); }; export default LoginPage;
Login.js
import React from 'react'; import styled from 'styled-components'; const LoginBox = styled.div` padding: 30px 0 30px 0; `; const Login = () => { return ( <LoginBox> <h1>로그인 페이지입니다.</h1> </LoginBox> ); }; export default Login;
11.props(변수,함수 passing하기)
HomePage.js
import React, { useEffect, useState } from 'react'; import Footer from '../components/Footer'; import Header from '../components/Header'; import Home from '../components/home/Home'; const HomePage = () => { //http요청 (jquery ajax, fetch, axios(다운)) const [boards, setBoards] = useState([]); const [number, setNumber] = useState(0); //빈 배열이면 한번만 실행 useEffect(() => { //다운로드 가정 =fetch(),axios(),ajax() let data = [ { id: 1, title: "제목1", content: "내용1" }, { id: 2, title: "제목1", content: "내용2" }, { id: 3, title: "제목1", content: "내용3" }, ]; setBoards([...data]); }, []) return ( <div> <Header /> <Home boards={boards} setBoards={setBoards} number={number} setNumber={setNumber} /> <Footer /> </div> ); }; export default HomePage;
Home.js
import React, { useState } from 'react'; //Function 방식 //class 방식 const Home = (props) => { //구조분할 할당 const { boards, setBoards, number, setNumber } = props; return ( <div> <h1>홈페이지 입니다. {number} </h1> <button onClick={() => setNumber(number + 1)}>번호 증가</button> <button onClick={() => setBoards([])}>전체 삭제</button> {boards.map((board) => <h3>{board.title} - {board.content}</h3> )} </div> ); }; export default Home; <h1>홈페이지 입니다.</h1>
12. styled component props
HomePage.js
import React, { useEffect, useState } from 'react'; import Footer from '../components/Footer'; import Header from '../components/Header'; import Home from '../components/home/Home'; const HomePage = () => { //http요청 (jquery ajax, fetch, axios(다운)) const [boards, setBoards] = useState([]); const [number, setNumber] = useState(0); const [user, setUser] = useState([]); //빈 배열이면 한번만 실행 useEffect(() => { //다운로드 가정 =fetch(),axios(),ajax() let data = [ { id: 1, title: "제목1", content: "내용1" }, { id: 2, title: "제목1", content: "내용2" }, { id: 3, title: "제목1", content: "내용3" }, ]; setBoards([...data]); setUser({ id: 1, username: 'ssar' }); }, []) return ( <div> <Header /> <Home boards={boards} setBoards={setBoards} user={user} number={number} setNumber={setNumber} /> <Footer /> </div> ); }; export default HomePage;
Home.js
import React, { useState } from 'react'; import styled from 'styled-components'; const StyledDeleteButton = styled.button` color :${(props) => (props.user.username === 'ssar' ? 'blue' : 'red')}; `; const Home = (props) => { //구조분할 할당 const { boards, setBoards, number, setNumber, user } = props; return ( <div> <h1>홈페이지 입니다. {number} </h1> <button onClick={() => setNumber(number + 1)}>번호 증가</button> <StyledDeleteButton user={user} onClick={() => setBoards([])}>전체 삭제</StyledDeleteButton> {boards.map((board) => <h3>{board.title} - {board.content}</h3> )} </div> ); }; export default Home; <h1>홈페이지 입니다.</h1>
13. styled-component 스타일 상속
import React, { useState } from 'react'; import styled from 'styled-components'; const StyledDeleteButton = styled.button` color :${(props) => (props.user.username === 'ssar' ? 'blue' : 'red')}; `; //스타일 확장 const StyledAddButton = styled(StyledDeleteButton)` background-color: green; `; const Home = (props) => { //구조분할 할당 const { boards, setBoards, number, setNumber, user } = props; return ( <div> <h1>홈페이지 입니다. {number} </h1> <button onClick={() => setNumber(number + 1)}>번호 증가</button> <StyledAddButton user={user}>더하기</StyledAddButton> <StyledDeleteButton user={user} onClick={() => setBoards([])}>전체 삭제</StyledDeleteButton> {boards.map((board) => <h3>{board.title} - {board.content}</h3> )} </div> ); }; export default Home; <h1>홈페이지 입니다.</h1>
14.라우팅하기(react router dom)
1) react router dom
npm install react-router-dom@
2) index.js 파일에서
BrowserRouter 감싼다.
index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom'; import Header from './components/Header'; import Footer from './components/Footer'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <BrowserRouter> <Header /> <App /> <Footer /> </BrowserRouter> </React.StrictMode> ); reportWebVitals();
App.js
import { Routes, Route } from 'react-router-dom'; import HomePage from './pages/HomePage'; import LoginPage from './pages/LoginPage'; import NotFound from './pages/NotFound'; import 'bootstrap/dist/css/bootstrap.min.css' import './App.css'; function App() { return ( <Routes> <Route path="/" element={<HomePage />} /> <Route path="/login" element={<LoginPage />} > <Route path="/login/:id" element={<LoginPage />} /> </Route> <Route path="*" element={<NotFound />} /> </Routes > ); } export default App;
16. 글쓰기, 글목록보기. 글삭제
import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; const StyledItemBoxDiv = styled.div` border: 1px solid black; padding: 10px; height: 100px; margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center; `; const StyledInput = styled.input` width: 300px; height: 30px; margin-bottom:10px; `; const StyledTextArea = styled.textarea` width: 300px; height: 130px; margin-bottom:10px; `; const ListPage = () => { const [no, setNo] = useState(6); const [post, setPost] = useState({ id: no, title: "", content: "" }) const [posts, setPosts] = useState([ { id: 1, title: "제목1", content: "내용1" }, { id: 2, title: "제목2", content: "내용2" }, { id: 3, title: "제목3", content: "내용3" }, { id: 4, title: "제목4", content: "내용4" }, { id: 5, title: "제목5", content: "내용5" } ]); const hadleWrtie = () => { if (post.title === "") { alert("제목을 입력하세요"); return; } if (post.content === "") { alert("내용을 입력하세요"); return; } post.id = document.form1.id.value; post.title = document.form1.title.value; setPosts([...posts, post]); setNo(no + 1); setPost({ id: no, title: "", content: "" }); document.form1.content.value = ""; } const handleForm = (e) => { //computed property names 문법 (키값 동적할당) setPost({ ...post, [e.target.name]: e.target.value }); console.log("[post, setPost] ", post.title, post.content); } const deletPost = (e) => { if (window.confirm("정말 삭제 하시겠습니까?")) { const id = e.target.getAttribute("data-id"); const update = posts.filter(n => { return parseInt(n.id) !== parseInt(id) }); console.log(id, update); setPosts(update); } } return ( <div> <div> <h1>글쓰기 페이지</h1> <hr /> <form name='form1'> <input type="hidden" name='id' value={no} onChange={handleForm} /> <StyledInput type="text" placeholder='제목을 입력하세요.' name='title' value={post.title} onChange={handleForm} /> <br></br> <StyledTextArea type="text" placeholder='내용을 입력하세요.' name='content' onChange={handleForm} >{post.content}</StyledTextArea> <br></br> <button type='button' onClick={hadleWrtie}>글쓰기</button> </form> </div> <br /><br /><br /><br /> <h1>글목록 페이지</h1> {posts.map((post) => ( <StyledItemBoxDiv> <div> 번호 :{post.id} / 제목: {post.title} / 내용 : {post.content} </div> <div> <button onClick={deletPost} data-id={post.id}>삭제</button> </div> </StyledItemBoxDiv> ))} </div> ); } export default ListPage;
댓글 ( 4)
댓글 남기기