React

 

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 
안녕11333
안녕 {a === 10 ? '1' : '999'}

해딩태그 {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 감싼다.

 

React Router v6 튜토리얼

 

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;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

react

 

about author

PHRASE

Level 60  라이트

세상을 다스리는 것은 사람의 힘으로 하는 것이지 법률에 의해서 되는 것은 아니다. -순자

댓글 ( 4)

댓글 남기기

작성

React 목록    more