배포의 단계

개발(develop) - 빌드(build) - 배포(deploy)

개발 - 만드는 단계

빌드 - 어플리케이션 가동의 필요한 것들을 통합하고, 경량화 시키는 단계 (배포를 위한 준비과정)

배포 - 서버에 반영을 하는 것

 

웹앱을 무료로 배포하는 다양한 방법이 존재합니다.

  1. 깃허브페이지
  2. 구글 firebase
  3. 기타등등

이번에는 firebase를 이용해서 배포를 진행하도록 합니다.


리액트 빌드하기

1. 프로젝트 최상위 루트에서 실행하세요

npm run build

2. 실행하면 build폴더가 생성됩니다.

 

 

3. build폴더 안에는 개발 단계에서 복잡한 코드를 경량화해서 index.html을 생성해줍니다.

4. 바로 실행하게 되면 서버가 아니라서 정상적으로 실행이 안 될텐데요. 아래 명령어로 1회용 서버로 실행 시켜보세요.

 

 

npx serve -s build

5. http://localhost:3000으로 들어가보면 빌드된 결과물이 나옵니다.

 


파이어베이스 배포하기

 

파이어베이스는 2011년 파이어베이스사가 개발하고 2014년 구글에 인수된 모바일 및 웹 애플리케이션 개발 플랫폼이다. 위키백과

 

 

1. firebase에 가입하고 콘솔로 이동합니다.

 


2. 프로젝트를 생성해 주세요.


3. hosting으로 들어갑니다.


4. 시작하기를 클릭해서 단계 별로 실행합니다. (firebase문서에 상세하게 나와있습니다^^)


5. 컴퓨터에는 node.js가 설치되어야 합니다.

  • vs코드에서 아래 명령문을 실행합니다.
  • 프로젝트에 최상위 경로에서 진행해 주세요.

 

파이어베이스 설치

npm install -g firebase-tools

파이어베이스 로그인

npx firebase login

파이어베이스 설정시작

npx firebase init

firebase 시작할거야? y


파이어 베이스에서 시작할 기능을 스페이스로 선택하세요.

hosting을 선택합니다. (space선택 -> 엔터)

 


너의 기본 경로를 어디로 사용 할거에요?? build

  • 리액트는 빌드시 폴더가 build로 생성되기 때문에 public폴더를 build로 잡아주세요 (디폴트 public)

싱글페이지 앱으로 구성할거에요? yes

깃허브에서 자동으로 배포하게 만들거에요? no

index파일이 있는데 덮어쓸까요? no

  • yes를 선택하면 build했던 내용이 기본파일로 덮어집니다. 

 

 

6. 파이어 베이스에 배포

npx firebase deploy

7. hosting url에서 확인하면 됩니다.

 

8. 이후에 배포는?

  • npm run build (리액트 빌드)
  • npx firebase deploy (파이어베이스에 배포)만 하면됩니다.

 

'Front-End > React' 카테고리의 다른 글

10. 리액트 ContextAPI  (0) 2023.01.02
9. Ajax로 외부 데이터 통신하기  (0) 2022.12.29
8. React라우터  (0) 2022.12.28
7. React에 CSS적용하기  (0) 2022.12.27
6. 리액트 기본훅  (0) 2022.12.26

데이터를 전역으로 관리하자 ContextAPI or Redux

API문서

https://ko.reactjs.org/docs/context.html

 

React를 하다보면 여러 컴포넌트를 거쳐서 자료를 전달해야 하거나, 동시에 같은 자료를 사용해야 하는 경우가 생깁니다.

  • Context는 리액트 컴포넌트 간에 어떠한 값을 공유 할 수 있게 해주는 기능입니다.
  • 주로 Context는 전역적(global)으로 필요한 값을 다룰 때 사용합니다.

Props로만 데이터를 전달하는 것은 한계가 있다.

리액트 에서는 일반적으로 컴포넌트에게 데이터를 전달해 주어야 할 때 Props를 통해 전달합니다.

그런데, 이 컴포넌트의 형태가 복잡하다면 어떻게 될까요?

 

 

 

 

https://velopert.com/3606

G에서 변경된 값을 J로 가져가려면 Root를 거쳐 J로 돌아가야 합니다.

G값을 핸들링하는 함수 또한 Root에서 선언 해야합니다.

Props를 통해 핸들링 함수를 자식 컴포넌트(JS는 변수로 함수를 전달가능) 로 전달해줘야 합니다.

 

이런 문제는

Context API 또는 Redux를 사용하여 공통(전역)으로 사용하는 데이터를 외부에서 편리하게 사용할 수 있습니다.

 

 

 

 

ConextAPI 사용방법

 

createContext() 훅 

  • ContextAPI를 생성합니다.
const 사용할이름 = createContext(초기값)

 

provider와 consumer

Provider Component 부모에서 사용 Context의 변화를 하위 컴포넌트에 알린다.
Consumer Component 자식에서 사용 부모 Component중 가장 가까운 Provider가 전달하는 데이터를 받아서 사용한다.

 

구현순서

  1. ContextAPI를 생성한다.
  2. 자식 컴포넌트에서는 Consumer를 이용해서 데이터 받기
  3. 부모 컴포넌트에서는 Provider를 사용해서 value값을 제어한다.

ContextAPI.js 생성

import { createContext } from "react";

//컨텍스트의 기본상태 지정
const ColorContext = createContext({color : 'red'})

export default ColorContext; //외부에서 사용하도록 export

 

ColorComponent.js 안에서 Consumer의 사용

  • Context 변화를 사용하는 React 컴포넌트입니다. 이 컴포넌트를 사용하면 함수 컴포넌트안에서 Context를 사용 할 수 있습니다.
  • Context.Consumer의 자식은 함수여야합니다. (첫번째 매개변수에서 context값을 얻습니다)
  • return에 화면에 렌더링할 JSX를 만듭니다.
//...
const ColorComponent = () => {

    return (
        <ColorContext.Consumer>
            {/* ColorContext 안에 Consumer를 사용하고 
            JSX자리에 함수로 return을 처리하는 구문을 사용함 */}
            {
                (value) => (
                    <div style={{background: value.color}}> 
                        ConTextAPI사용<br/>
                        값: {value.color}
                    </div>
                )
            }
        </ColorContext.Consumer>

    )

}

export default ColorComponent;

App.js 안에서 Provider의 사용

  • Context에 포함된 React 컴포넌트인 Provider는 context를 사용하는 컴포넌트들에게 context의 변화를 알리는 역할을 합니다.
  • Provider 컴포넌트는 value prop을 받아서 이 값을 하위에 있는 컴포넌트에게 전달합니다.
  • Provider 하위에서 context를 사용하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.
//...
const App = () => {

    return (
        <ColorContext.Provider value={{color: 'green'}}>
            <ColorComponent/>
        </ColorContext.Provider>

    )
}

export default App;

 


Provider와 Consumer를 독립적으로 분리하기

 

  • ContextAPI는 전역으로 사용할 값이기 때문에 파일을 독립적으로 분리해서 작성하도록 변경합니다.
  • 하위 컴포넌트에서는 훅을 이용해서 더욱 편리하게 사용할 수 있습니다.

 

useContext() 훅

  • 컴포넌트에서 context API를 편하게 사용하는 훅입니다
  • 리턴은 객체이고 첫번째 값은 상태값, 두번째는 값을 저장하는 setter를 가진 객체를 반환합니다.
const {state, action} = useContext(컨택스트API객체)

 

구현순서

  1. ContextAPI2.js 생성 (Provider재정의, Consumer를 외부로 export)
  2. App.js에서 Provider감싸기
  3. A.js 훅 으로 컨텍스트 사용하기

ContextAPI2.js 에서는...

import { createContext, useState } from "react";


//1. 초기값 설정
const UserContext = createContext({
    state : {id: 'aaa', name : 'bbb'},
    action : {
        setUser : () => {}
    }
});

//2. Provider컴포넌트 재정의
//매개값의 이름은 반드시 children으로 구조분해할당 합니다.
//useState를 활용해서 데이터를 관리합니다.
const UserProvider = ({children}) => {
    const [user, setUser] = useState({id: 'aaa', name: 'bbb'});
    const value = {
        state : user,
        action : {setUser}
    }
    //Provider 반환
    return (
        <UserContext.Provider value={value}>{children}</UserContext.Provider>
    )
}

//3. 외부에서 사용가능 하도록 consumer, provider 반환
const UserConsumer = UserContext.Consumer;
export {UserProvider, UserConsumer}

export default UserContext;

App.js에서는...

 

import A from "./component3/A";
import B from "./component3/B";
import { UserProvider } from "./contexts/ContextAPI2";

const App = () => {

    return (
        <UserProvider>
            <A/>
            <B/>
        </UserProvider>

    )
}

export default App;

A.js 그리고 B.js에서는..

import { useContext, useRef } from "react";
import UserContext, { UserConsumer } from "../contexts/ContextAPI2";

const A = () => {
    //useRef훅
    const input1 = useRef(null);
    const input2 = useRef(null);

    //useContext훅 - 을 이용해서 값 조회 or 값 변경
    //Context API를 훅으로 사용
    const {state, action} = useContext(UserContext);

    const handleClick = () => {
        action.setUser({id: input1.current.value,
                       name: input2.current.value});
        
        input1.current.value = '';               
        input2.current.value = '';               
    }

    return (
        <div>
            <h3>A컴포넌트</h3>
            <input type="text" ref={input1}/>
            <input type="text" ref={input2}/>
            <button onClick={handleClick}>데이터변경</button>

            <div>
                {state.id}<br/>
                {state.name}<br/>
            </div>

        </div>
    )
}

export default A;

'Front-End > React' 카테고리의 다른 글

11. firebase에 react배포하기  (0) 2023.01.04
9. Ajax로 외부 데이터 통신하기  (0) 2022.12.29
8. React라우터  (0) 2022.12.28
7. React에 CSS적용하기  (0) 2022.12.27
6. 리액트 기본훅  (0) 2022.12.26

프로미스는 자바스크립에 내장된 내장객체 입니다
프로미스 객체에서는 2가지를 형태를 지닙니다.

 

1. 상태(state) 

  • pending : 수행중
  • fullfilled : 성공적 완료
  • rejected : 실패

2. 프로듀서 - 정보를 제공하는 제공자(즉, Promise)
    컨슈머 - 사용자(즉, 호출하는사람)

 


프로미스 생성
executor콜백함수를 전달해야 하며 executor콜백함수는 다시 resolve함수와 reject함수를 받습니다.

//매개변수는 컨슈머가 분명 콜백함수를 전달할거야!(그 콜백함수로 리턴해줄게!)
let promise = new Promise( (success, fail) => {

    //producer 입장에서 성공했을 때 성공을 알리는 함수
    success("success"); 

    //producer 입장에서 실패했을 때 실패를 알리는 함수
    //fail(new Error("fail"));

});

console.log(promise)

프로미스의 사용 then(), catch()

  • then은 promise가 정상적으로 실행 된다면, 결과를 실행시켜주는 콜백함수이다.
  • catch는 promise가 실패했을 때, 결과를 실행시켜주는 콜백함수이다.
//....생략
promise.then( data => console.log(data) )
       .catch( error => console.log(error) )

프로미스의 적용

결과가 언제 돌아갈지 모르지만, 내가 이것을 완료되면 Promise를 전달해 줄테니, 너는 then함수만 이용해서 결과를 받아서 처리해!

 

ajax fetch()의 내부모습 예시

//자바스크립트로 구현되어있는 fetch라고 가정
function myfetch(req) { 
    //비동기적 실행.. 10초..
    return new Promise( (success, fail) => {
        success("data....");
    });
}

//fetch와 같은 실행구조를 보인다.
myfetch("http://localhost:5502/~~~~~").then( response => console.log(response) );

 


Promise를 더 쉽게 사용할 수 있게 해주는 async(이거 비동기야)

async, await규칙

  1. 어싱크 함수 안에서 어웨잇을 사용한다
  2. function 앞에 async 키워드를 추가 함수는 언제나 프라미스를 반환 합니다.
  3. 리턴이 프로미스라면 await을 적용하고 then절을 없앨 수 있다.

 

async란 function앞에 선언하며, return값을 자동으로 Promise로 변경해주는 역할을 한다.
즉, 비동기 함수의 실행 형태로 변경해준다.

async function myfetch(req) {
    //비동기적 실행.. 10초..
    return "data....";
}


//var result = myfetch()
//console.log(result); //Promise

myfetch("http://localhost:5502/~~~~~").then( response => console.log(response) );

 

Promise를 더 쉽게 사용할 수 있게 해주는 await(기다려)

리턴이 프로미스라면 await을 적용하고 then절을 없앨 수 있다. (단 async함수 안에서만 사용 가능합니다)

(async function() {
    let data = await myfetch();
    console.log(data)

})();

async, await의 장점

  1. 코드의 간결성
  2. 어싱크, 어웨잇은 동기적방식(순서를) 보장한다

 

 

'Front-End > JavaScript(ES6)' 카테고리의 다른 글

JS ES6 문법 한눈에 보기  (0) 2022.12.20

목차

  1. Ajax란?
  2. ES6의 fetch를 이용해서 리액트에서 데이터 처리하기
  3. Axios로 데이터 처리하기 
  4. async, await 적용하기

 

AJAX ( Asynchronous Javascript and XML) 은 웹 페이지의 이동없이 필요한 데이터만 전송하는 기술입니다.

 

ajax

웹 어플리케이션에서 데이터를 가져올 때 서버쪽 데이터가 필요할 때 ajax기법을 사용하게 됩니다.

이 작업은 시간이 오래 걸릴 수도 있기 때문에 비동기적으로 처리하게 됩니다.

비동기(asynchronous)는 요청이 끝날 때 까지 기다리는 것이 아니라, 동시에 여러 작업을 수행하게 됩니다.

 

나중에 react에서는 다른 서버의 REST API와 통신을 이용하여 데이터베이스 데이터를 가져올 수 있습니다.

 


ES6의 fetch를 이용해서 리액트에서 데이터 처리하기

Promise = fetch(요청주소)

 

1. 이벤트 클릭시 처리하기

  • 데이터를 가져와서 useState()에 저장하는 작업입니다.
  • 극단적으로 표현해 데이터 통신에 100초 가 소요되면 useState는 100초 간 undefined 상태가 됩니다.
  • 렌더링 시에 에러를 나타내기 때문에, undefined에 관한 처리를 동시에 진행합니다.

 

import { useEffect, useState } from "react";

const App = () => {

    let [raw, setRaw] = useState();

    const handleClick = () => {
        fetch('https://raw.githubusercontent.com/yopy0817/data_example/master/hi.json')
        .then( response => response.json() )
        .then( data => {
            //console.log(data)
            setRaw(data)
        })
    }

    return (
        <div>
            <h3>클릭시에 fetch로 데이터 가져오기</h3>
            <button type="button" onClick={handleClick}>데이터로드</button>
            {raw !== undefined ?
                <div>
                    {raw.userId}<br />
                    {raw.userPw}<br />
                    {raw.userName}<br />
                </div>
                : undefined
            }
        </div>
    )

}

export default App;

2. 화면 렌더링 완료시 데이터 처리하기 useEffect() 훅 사용

  • 비동기 작업을 컴포넌트에 바로 쓰고 state를 변경하면, 무한루프에 빠지게 됩니다.
  • 그래서 useEffect() 훅을 이용하여 첫번째 렌더링 완료시만 데이터만 가져오도록 처리합니다.
import { useEffect, useState } from "react";

const App = () => {

    let [data, setData] = useState()

    //렌더링 완료시 데이터 로드
    useEffect( () => {
        fetch('https://raw.githubusercontent.com/yopy0817/data_example/master/hi.json')
        .then( response => response.json() )
        .then( data => {
            setData(data)
        })
    }, [])


    return (
        <div>
            <h3>로딩시에 fetch로 데이터 가져오기(같은표현)</h3>
            {data && <div>
                        {data.userId}<br />
                        {data.userPw}<br />
                        {data.userName}<br />
                    </div>
            }
        </div>
    )

}

export default App;

Axios로 데이터 처리하기

엑시오스는 비동기를 더편하게 처리하는 라이브러리 입니다.
 
엑시오스 설치
npm add axios

엑시오스

Promise = axios.get(요청주소)

 

1. 이벤트 클릭시 처리하기 (fetch와 거의 같음 😊)

import axios from "axios";
import { useState } from "react";

const App = () => {

    const handleClick = () => {
        axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/hi.json')
        .then(response => {
            setData( response.data );
        })
    }

    return (
        <div>
            <h3>엑시오스데이터</h3>
            <button type="button" onClick={handleClick}>데이터로드</button>
            {data !== undefined ?
                <div>
                    {data.userId}<br />
                    {data.userPw}<br />
                    {data.userName}<br />
                </div>
                :
                undefined
            }
        </div>
    )
}
export default App;

async(이거 비동기임) , await(기다려) 적용하기

ES6의 문법입니다. 비동기 코드를 간결하게 작성할 수 있게 합니다.

 

구문의 내용을 잘모르거나 궁금하면 여기로
https://coding404.tistory.com/21

 

async, await규칙

  1. 어싱크 함수 안에서 어웨잇을 사용한다
  2. function 앞에 async 키워드를 추가 함수는 언제나 프라미스를 반환합니다.
  3. 리턴이 프로미스라면 await을 적용하고 then절을 없앨 수 있다.

 

비동기에서 3번의 데이터 통신을 한다고 가정합시다.

1,2,3,4,5,6의 순서로 출력될 것 같지만 아닙니다.

순서를 보장하지 않습니다.

    ...생략
    const handleClick = () => {
        axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/hi.json')
        .then(response => {
            console.log(response.data);
            console.log(1)
        })
        console.log(2)

        axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/hello.json')
        .then(response => {
            console.log(response.data);
            console.log(3)
        })
        console.log(4)
        
        axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/by.json')
        .then(response => {
            console.log(response.data);
            console.log(5)
        })
        console.log(6)
    }

Axios는 이미 Promise를 반환합니다.

Axios앞에 await을 사용할 수 있고, then() 절을 생략 할  수 있습니다.

Axios를 호출하는 부모함수에는 await을 반드시 달아줍니다.

 

async, await의 장점

  1. 코드의 간결성
  2. 어싱크, 어웨잇은 동기적방식(순서를) 보장한다

 

async, await적용하여 변경하기

const handleClick = async () => {
    let response = await axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/hi.json')
    console.log(response.data);
    setData( response.data );

    console.log(1);

    let response2 = await axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/hello.json')
    console.log(response2.data);

    console.log(2);

    let response3 = await axios.get('https://raw.githubusercontent.com/yopy0817/data_example/master/by.json')
    console.log(response3.data);

    console.log(3);

}

 

'Front-End > React' 카테고리의 다른 글

11. firebase에 react배포하기  (0) 2023.01.04
10. 리액트 ContextAPI  (0) 2023.01.02
8. React라우터  (0) 2022.12.28
7. React에 CSS적용하기  (0) 2022.12.27
6. 리액트 기본훅  (0) 2022.12.26

SPA란? (single page application)

하나의 페이지로 만들어진 어플리케이션을 의미합니다.

 

전통적 웹 어플리케이션 vs SPA

 

SPA는 html파일을 브라우저 측에서 로드하고, 필요한 데이터는 API와 ajax통신을 이용해서 처리합니다.

브라우저에서 사용자가 상호작용 하면 필요한 부분만 업데이트 해서 처리합니다.

멀티플랫폼 Android, IOS에 대응하여 웹뷰로 처리하는 목적으로도 사용됩니다.

 

SPA의 단점

  • 앱의 규모가 커지면, JS파일도 너무 커져서 로딩이 오래걸리게 됩니다.
  • 브라우저에서 렌더링이 완료되기 까지 비어있는 화면이 나오게 됩니다.
  • 그래서 규모가 큰 어플리케이션은 SSR(서버사이드 렌더링) 방식으로 처리합니다. (웹팩 설정 필요)

 

라우팅이란?

  • 브라우저의 주소상태에 따라 다양한 화면을 보여주도록 처리하는 것을 라우팅이라고 합니다.

 

사용이유

  • create-react-app로 프로젝트를 생성하게 되면 기본적으로  SPA에 CSR(클라이언트 렌더링) 입니다.
  • 하나의 페이지만 사용하게 되는 것입니다.
  • SPA이지만 라우터를 활용해서 사용자로 하여금 여러 페이지가 존재하는 것처럼 느껴지게 할 수 있습니다.

라우터 설치하고 프로젝트 시작하기

1. 라우터를 적용할 프로젝트 생성

npm create react-app 프로젝트명

2. 라우터 설치

npm add react-router-dom

3. 프로젝트 시작

npm start

라우터 적용하기

  1.  라우터를 사용할때는 index.js에서 App컴포넌트를 <BrowserRouter>로 감싸줍니다.
  2.  페이지 컴포넌트 만들기
  3.  App컴포넌트에서 <Routes>를 사용해서 분기하기
  4.  주소요청을 통해 확인하기

index.js

....
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>

);

 

 

App.js

  • /요청은 Home컴포넌트가 나타납니다
  • /user요청은 User컴포넌트가 나타납니다.
  • /info요청은 Info컴포넌트가 나타납니다.
function App() {

  return (
    <Routes>
        <Route path='/' element={<Home/>}/>
        <Route path='/user' element={<User/>}/>
        <Route path='/info' element={<Info/>}/>
    </Routes>
  );
}

export default App;

Link를 이용해서 다른페이지로 이동하기

  • link태그는 화면에서 a태그로 생성됩니다.
  • to 속성에는 연결할 요청주소를 적습니다.
  • 어느 컴포넌트든 사용할 수 있습니다.

/로 연결되는 Home

//.....
return (
	<ul>
		<li><Link to='/user'>회원페이지</Link></li>
	</ul>
)

URL파라미터 or 쿼리스트링

같은 컴포넌트라도 전달되는 데이터에 따라서 다른 내용을 보여줘야 하는 경우가 있습니다.

EX) 글 상세

이 때 URL주소의 매개변수를 전달 할 수 있고, 컴포넌트는 그 값을 받아서 사용 할 수 있습니다.

 

1. 쿼리스트링

  • 쿼리스트링은 주소의 ? 뒤에 키=값 의 형태로 넘어가는 매개값입니다.
  • 별도의 라우터 설정은 하지 않아도 됩니다.
  • 컴포넌트에서는 useLocation() 훅 or useSearchParams() 훅을 사용 해서 쿼리스트링을 받을 수 있습니다.
/경로?키=값&키=값

 

링크에서는...

//.....
return (
	<ul>
		<li><Link to='/user?id=aa123&key=1'>회원페이지(쿼리파람)</Link></li>
	</ul>
)

 

컴포넌트에서는....

 

 useLocation() 훅

const location = useLocation();   
 
 
useSearchParams() 훅 
 
  • 배열을 반환합니다.
  • 첫 번째 요소는 쿼리파라미터를 조회하거나 수정하는 get, set이 담긴 객체
  • 두 번째 요소는 쿼리파라미터를 객체로 업데이트 하는 함수 반환
const [객체, function] = useSearchParams() 
    const [obj, setObj] = useSearchParams();
    let id = obj.get("id"); //request.getParameter("키")
    let key = obj.get("key");

2. URL파라미터 👍

  • URL파라미터는 주소 뒤에 /경로/값/값 의 형태로 넘어가는 매개값입니다.
  • 라우터에 추가적인 설정이 필요합니다. ( /주소/:키 )
  • 컴포넌트에서는 useParams() 훅을 사용하여 URL파라미터를 받을 수 있습니다.

 

라우터에서는...

function App() {

  return (
    <Routes>
        .....
        <Route path='/info/:num' element={<Info/>}/>
    </Routes>
  );
}

export default App;

링크에서는...

 

//.....
return (
	<ul>
		<li><Link to='/info/1'>1번 info</Link></li>
		<li><Link to='/info/2'>2번 info</Link></li>
		<li><Link to='/info/3'>3번 info</Link></li>
	</ul>
)

 

컴포넌트에서는...

 

useParams() 훅

 

/param에는 link로 넘어온 키가 담겨 있습니다.

let param = useParams();

중첩라우터로 공통 부분 처리하기

  • 글페이지가 있고, 글에 따른 상세화면이 있다고 가정해 봅시다.
  • 라우터의 설정은 아래 처럼 보여질 수 있습니다.
  • 아래 설정은 두 라우터가 다르기 때문에 각각 다른 화면이 보입니다.
<Routes>
	<Route path='/board' element={<Board/>}/>
	<Route path='/board/:num' element={<BoardContent/>}/>
</Routes>

  • 만약 Board 목록 페이지를 공통으로 사용하고 상세페이지를 서브로 보여주도록 처리하려면 중첩라우터를 활용할 수 있습니다.
  • 중첩라우터로 적용되면 부모컴포넌트에서 <Outlet> 컴포넌트를 활용해서 하위 라우터를 보여지게 할 수 있습니다.
<Routes>
	<Route path='/board' element={<Board/>}>
		<Route path=':num' element={<BoardContent/>}/>
	</Route>
</Routes>

 

Board에서는...

const Board = () => {

    return (
        <div>
            <h3>게시글목록</h3>
            <ul>
                <li><Link to='/board/1' >글1</Link></li>
                <li><Link to='/board/2' >글2</Link></li>
                <li><Link to='/board/3' >글3</Link></li> 
             </ul>

            {/* Oulet컴포넌트가 사용된 자리에 중첩된 내용이 보여지게됩니다 */}
            <Outlet/>
        </div>
    )
}

export default Board;

 

BoardContent에서는...

const BoardContent = () => {

    let {num} = useParams()

    return (
        <div>
            <h3>글 상세페이지</h3>
            {num}번 글입니다      
        </div>
    )
}

export default BoardContent;

 

결과


헤더 태그 분리하기

 


라우터의 부가적인 기능

1. NavLink 컴포넌트

  •  링크에서 사용하는 경로가 라우터의 경로와 일치하면 특정스타일을 적용 (활성화기능)

 

2. useNavigate() 훅 vs Navigate 컴포넌트 

useNavigate() 훅

  • JS의 history객체를 대신합니다.
  • 이벤트에서 사용

Navigate 컴포넌트 

  • 리다이렉트기능 
  • 렌더링시에 사용

 


NavLink컴포넌트 

  • NavLink는 링크의 경로가 라우터의 경로와 일치하면 특정스타일을 적용해 줍니다.
  • NavLink는 style속성을 제공하합니다
  • style속성에는 실행시킬 함수를 작성합니다.
  • 이 함수에 매개변수로 {isActive : boolean}객체를 넣어주는데, 활성화 여부를 표시가 가능합니다.
  • 사용은 반드시 {isActive}변수로 구조분해할당 합니다.

 

Board컴포넌트 에서는...

 

const Board = () => {

    return (
        <div>
            <h3>게시글목록</h3>
            <ul>
                {/* 
                <li><Link to='/board/1' >글1</Link></li>
                <li><Link to='/board/2' >글2</Link></li>
                <li><Link to='/board/3' >글3</Link></li> 
                */}
                <li><NavLink to='/board/1' style={
                    ({isActive}) => {
                    return isActive ? myStyle : undefined  
                    }
                }>글1</NavLink></li>
                <li><NavLink to='/board/2' style={({isActive}) => (isActive ? myStyle : undefined  )}>글2</NavLink></li>
                <li><NavLink to='/board/3' style={({isActive}) => (isActive ? myStyle : undefined  )}>글3</NavLink></li> 
            
             </ul>

            {/* Oulet컴포넌트가 사용된 자리에 중첩된 내용이 보여지게됩니다 */}
            <Outlet/>
        </div>
    )
}

export default Board;

 


useNavigate() 훅

  • useNavigate훅 은 특정 event가 발생할 때,  url을 조작할 수 있는 함수를 제공합니다.
  • react v6 에서 useHistory 가 변화한 것입니다. (JS의 history객체를 대신 합니다)
let navigator = useNavigate();
import { Fragment } from "react";
import { NavLink, Outlet, useNavigate } from "react-router-dom";

const Header = () => {
    //useNavigate() 훅
    let nav = useNavigate();

    const goHome = () => {
        nav('/내가원하는 주소') 
    }
    return (
    	<button onClick={goHome}>이동</button>
    )

}
export default Header;

JS의 history를 다루는 기능도 제공합니다.

예시) history.go(-1) 

예시) history.go(1) 

  ...
  let nav = useNavigate();
  
  return(
      <>
          <button onClick={() => nav(-1)}>
            Go back
          </button>
          <button onClick={() => nav(1)}>
            Go forward
          </button>
      <>
  )

Navigate 컴포넌트

  • <Navigate> 컴포넌트는 렌더링 될 때 현재 위치를 변경합니다.
  • useNavigate()훅과 비슷해보이지만 useNavigate()훅은 렌더링 과정에 사용할 수 없습니다.
const MyPage = () => {
    /*
    렌더링 과정에 nav를 쓰지말라는 경고 후 작동이 안됩니다.
    let nav = useNavigate()
    let loginYN = false;
    if(!loginYN) {
        nav('/');
    }
    */
	
    //Navigate컴포넌트
    let loginYN = false;
    if(!loginYN) {
        return <Navigate to='/' replace={true}/>
    }

    return (
        <div>
            여기는 권한있는 사람만 들어옴
        </div>
    )

}
export default MyPage;

'Front-End > React' 카테고리의 다른 글

10. 리액트 ContextAPI  (0) 2023.01.02
9. Ajax로 외부 데이터 통신하기  (0) 2022.12.29
7. React에 CSS적용하기  (0) 2022.12.27
6. 리액트 기본훅  (0) 2022.12.26
5. 컴포넌트 반복  (0) 2022.12.23

리액트 스타일링

1. 태그에 직접 지정하기

2. 일반 css파일로 적용하기

3. css모듈로 적용하기

 

css파일 이름 규칙

컴포넌트의 이름을반드시 포함해서 만듭니다
EX) App.js - App.css
 

1. 태그에 직접 디자인을 적용 할 때는 {}로 묶어줍니다 
  •  css속성중 - 은 카멜표기법으로 대체됩니다.
style={{css속성: 값, css속성: 값}}
<p style={{color: 'white', textAlign: 'center'}}>안녕하세요!!</p>

2. 일반CSS문법으로 디자인을 해주면 되고 import로 가져오면 됩니다.

 

App.css

.app_header {
    height: 50px;
    line-height: 50px;
    background-color: #000;
    margin: 0;
    padding: 0;
}

App.js

import './css/App.css'; //일반css파일로 디자인
......생략

3. CSS모듈사용하기

  • 파일은 컴포넌트명.module.css 형식으로 만듭니다.
  • css파일은 import구문으로 가져옵니다.
  • 이 방식은 선택자에 고유한 해시값을 부여함으로 다른파일과 디자인의 중복을 막아줍니다.
  • :global 키워드를 이용해서 전역 선택자(이름) 선언이 가능합니다.

App.module.css 파일

.app_wrap {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    text-align: center;
    background-color: #fff;
    height: 100vh;
    margin: 0;
    padding: 0;
}

/* 전역선택자로 이름정하기 */
:global .title {
    color: pink;
    font-weight: 900;
}

App.js 파일

  1. css파일은 특정 이름으로 import합니다.
  2. style={특정이름.선택자 로} 적용합니다.
  3. :global 키워드는 이름으로 바로 사용하면 됩니다.
import styled from './css/App.module.css'; //css모듈로 디자인

const App = () => {
    return (
        <Fragment>
            <section className={styled.app_wrap}> {/* css모듈 app_wrap적용 */}
                 <p className="title">CSS모듈로디자인!</p> {/* css모듈의 전역선택자 적용 */}
            </section>
        </Fragment>
    )
}

export default App;

 

'Front-End > React' 카테고리의 다른 글

9. Ajax로 외부 데이터 통신하기  (0) 2022.12.29
8. React라우터  (0) 2022.12.28
6. 리액트 기본훅  (0) 2022.12.26
5. 컴포넌트 반복  (0) 2022.12.23
4. 리액트 이벤트 핸들링  (0) 2022.12.21

훅(HOOK) 이란?

  1. 리액트 컴포넌트는 클래스형 컴포넌트(Class component)와 함수형 컴포넌트(Functional component)로 나뉩니다.
  2. 리액트 훅은 새로운 기능으로 React 16.8버전에 새로 추가된 기능
  3. 함수형태의 컴포넌트에서 사용되는 몇가지 기술을 Hook이라고 부른다. (useState, userEffect 등)
  4. 리액트 훅은 함수형 컴포넌트가 클래스형 컴포넌트의 기능을 사용할 수 있도록 해주는 기능이다.

훅의 규칙

  • 최상위 에서만 Hook을 호출해야 한다
    • 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하면 안된다.
    • 이 규칙을 따르면 컴포넌트가 렌더링될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장된다.
  • 리액트 함수 컴포넌트에서만 Hook을 호출해야 한다.

 

 

반드시 알아야 할 기본 훅

useState(초기값) 

useState() : 배열반환 
첫번째 배열의 요소에는 현재값을, 두번째 요소는 상태를 변경하는 (setter) 를 반환합니다.
 

const [data, setData] = useState('초기값')

useEffect(실행시킬 콜백함수, 값에 따른 렌더링 지정 ) 

userEffect의 첫번째 매개변수는 실행시킬 콜백함수

userEffect의 두번째 매개변수는 배열[]을 사용하여 특정값이 update 될 때만 실행시켜 줄 수 있습니다.

 

useEffect() 는 컴포넌트의 라이프 사이클을 다룹니다.
리액트 컴포넌트가 mount, mount이후, unmount때 마다 특정작업을 수행합니다.

라이프 사이클

mount 이후 - 컴포넌트가 마운트 됨, 즉 컴포넌트의 첫번째 렌더링이 마치면 호출되는 메서드 입니다.

클래스형 componentDidMount() 대체

함수형 훅

useEffect( () => {
	console.log(`렌더링완료`);
});

 

mount 이후 업데이트 될 때는 실행되지 않으려면, 두번째 매개변수 배열를 줍니다.

 

useEffect( () => {
	console.log(`처음만 실행됩니다`);
}, []);​

update 이후 - 특정값에 의해 컴포넌트가 업데이트 되고 난 후 발생합니다.

클래스형 componentDidUpdate() 대체

함수형 훅

const HookEffect = () => {
    //useState
    const[name, setName] = useState('');
    const handleName = (e) => {
        setName( e.target.value );
    }

    //특정값이 업데이트 될 때만 실행해주려면 두번째 매개변수에 값을 state값을 지정합니다
    useEffect( () => {
        console.log(`name이 업데이트 시 실행됩니다`)
    }, [name]);

    return (
        <div>
            
            이름:<input type="text" onChange={handleName}/><br/>
            이름:{name}
        </div>
    )
}

export default HookEffect;

unmount직전 - 컴포넌트가 화면에서 사라지기 직전에 호출됩니다.

클래스형 componentWillUnMount() 대체

함수형 

const HookEffect = () => {
    //useState
    const[name, setName] = useState('');
    const handleName = (e) => {
        setName( e.target.value );
    }
    
	//useEffect    
    useEffect( () => {
        console.log(`name이 업데이트 시 실행됩니다`)
        
        //unmount이후 실행됩니다.
        return () => {
            console.log(`unmount에 실행됩니다.`);
        }
    }, [name]);

    return (
        <div>
            이름:<input type="text" onChange={handleName}/><br/>
            이름:{name}
        </div>
    )
}

export default HookEffect;

특정 태그에 이름달기 useRef()

useRef(초기값) 
const 사용할이름 = useRef(null);

 

이벤트를 사용하다 보면 특정 태그에 접근해서 핸들링 하는 경우가 생깁니다.

arrow function에 event 매개변수를 이용해서, 자신 태그에는 접근할 수 있지만, 다른태그는 핸들링 하기가 어렵습니다.

이런경우 useRef() 훅을 이용해서 특정태그에 이름을 지정하고 핸들링 할 수 있습니다.

 

const HookRef = () => {
    //useState
    const [form, setForm] = useState({data: '', result: '' });
    //useRef
    const inputTag = useRef(null);
    //인풋핸들링
    const handleChange = (e) => {
        setForm( {data :e.target.value} ); //인풋값이 변할때마다 data변수 변화
    }
    
    //버튼핸들링 - 클릭시 state는 변경하고, input태그에 포커스
    const handleClick = (e) => {
        setForm( {data: '', result: form.data})
        //useRef의사용 - current로 ref의 현재태그에 접근가능
        inputTag.current.focus()
    }

    return (
        <div>
            할일: <input type="text" value={form.data} onChange={handleChange} ref={inputTag} />
            <button type="button" onClick={handleClick}>등록하기</button>

            <br/>
            결과: {form.result}

        </div>
    )
}

export default HookRef;

훅의 종류는 이뿐이 아니고 굉장히 많습니다.

추후 필요한 hook들은 추가 되거나 뒤에서 학습합니다.

'Front-End > React' 카테고리의 다른 글

8. React라우터  (0) 2022.12.28
7. React에 CSS적용하기  (0) 2022.12.27
5. 컴포넌트 반복  (0) 2022.12.23
4. 리액트 이벤트 핸들링  (0) 2022.12.21
3. 리액트 State  (0) 2022.12.21
  1. 목록 요소들을 반복처리 할때는 map함수를 이용 합니다.
  2. 반복 컴포넌트에는 반드시 key props를 전달해야 합니다.

 

map함수는 실행한 결과를 가지고 새로운 배열을 만들 때 사용

array.map(callbackFunction(currenValue, index, array), thisArg) 
  • currenValue: 현재값
  • index: 현재인덱스
  • arrayt: 현재배열,
  • thisArg: callbackFunction 내에서 this로 사용될 값

 

filter - 요소개수만큼 반복하며 boolean을 이용한 새로운 list를 만듬

array.filter(callbackFunction(currenValue, index, array), thisArg) 
  • currenValue: 현재값
  • index: 현재인덱스
  • arrayt: 현재배열,
  • thisArg: callbackFunction 내에서 this로 사용될 값
const IterationComponent = () => {

    const arr = [1,2,3,4,5];
    const newArr = arr.map( item => item*10 ) // => 한줄일 경우 리턴

    console.log('map으로 생롭게 만들어진 newArr', newArr)
	
    return (
    	....
    )
}

map의 콜백함수의 리턴에 반복시킬 태그를 넣습니다.

리액트에서 key는 배열을 렌더링 시킬때 빠르게 변화를 감지하기 위해 사용하는 속성입니다.

key는 index대신 고유한 값을 넣어 주도록 권유 됩니다. (key를 넣지 않으면 props에러가 발생 됩니다.)

const IterationComponent = () => {

    const arr = [1,2,3,4,5];
    const newArr = arr.map((item, index) => <li key={index}>{item}</li>)

    return (
        <ul>
            {newArr}
        </ul>
    )
}

export default IterationComponent;

 

반복할 요소를 state에 넣고 처리하기

버튼 클릭시 인풋state의 값을 목록state에 추가하기

1. 반복처리할 state선언
2. input state, 인풋 핸들러선언
3. 버튼 클릭시 input state의 값을 목록state에 추가
import { useState } from "react";


const IterationComponent2 = () => {

    //1. 반복처리할 데이터 state
    const data = [{id:1, topic: 'hello'},
                  {id:2, topic: 'bye'} 
                 ];
    const [list, setList] = useState(data)
    const newData = list.map( item => <li key={item.id}>{item.topic}</li> )

    //2.인풋핸들러추가
    const [inputData, setInputData] = useState('')
    const handleChange = e => {
        setInputData(e.target.value) //input데이터 state로 관리
    }

    //3. 데이터 추가시 input의 값으로 1번 데이터 수정
    const handleClick = e => {
        let obj = {id: list[list.length-1].id + 1 , topic: inputData} //추가할데이터(마지막요소의 id+1, 인풋데이터)
        let newList = list.concat(obj) //state와 추가할 데이터 합치기(배열합치기)
        setList(newList); //state업데이트
        setInputData(''); //input값 비우기
    }

    return (
        <div>
            <hr/>
            <input type="text" onChange={handleChange} value={inputData}/>
            <button onClick={handleClick}>추가하기</button>
            <ul>
                {newData}
            </ul>
        </div>
    )

}

export default IterationComponent2;

 

 

 

 

 

 

'Front-End > React' 카테고리의 다른 글

7. React에 CSS적용하기  (0) 2022.12.27
6. 리액트 기본훅  (0) 2022.12.26
4. 리액트 이벤트 핸들링  (0) 2022.12.21
3. 리액트 State  (0) 2022.12.21
2. 리액트의 Components와 props  (0) 2022.12.21

이벤트 규칙

  1. 이벤트의 이름은 전부 카멜 표기법으로 표현됩니다. onkeyup -> onKeyUp
  2. 이벤트를 전달할 때는 {함수} 형태로 사용합니다

 

인풋값 핸들링 해보기

  1. 인풋의 값이 변화되는 이벤트 onChange 연결
  2. 이벤트 안 첫번째 매개변수에서 event객체 활용하기 (e.target.속성값)
  3. setter를 이용해서 state변경하기
const EventComponent = () => {

    const [name, setName] = useState('');
    let handleName = (e) => { //2.event객체 활용
        setName(e.target.value); //3.state변경 (input의 value도 변경)
    }
    return (
        <div>
            <h3>리액트 이벤트 핸들링</h3>
            <input type="text" name="name" onChange={handleName} value={name}/><br/> {/*1. 이벤트연결*/}
            <h3>체인지된 결과: {name}</h3>
        </div>
    )
}

useState를 하나로 관리하기(객체로 사용) 😊

const EventComponent2 = () => {
     
    const [form, setForm] = useState({name: '', topic: ''}); //객체 state
    
    let handleChange = (e) => {
        const copy ={...form, [e.target.name]: e.target.value } //spread문법으로 복사 후 키 값 수정
        setForm(copy); //state변경
    }

    let handleClick = () => {
        alert(`결과: ${form.name} 님의 할일: ${form.topic}`)
        setForm({name: '', topic: ''}) //state변경
    }
    
    return (
        <div>
            
            <h3>리액트 이벤트 핸들링(객체로 핸들링)</h3>
            <input type="text" name="name" onChange={handleChange} value={form.name}/><br/>
            <h3>체인지된 결과: </h3>

            <input type="text" name="topic" onChange={handleChange} value={form.topic} /><br/>
            <h3>체인지된 결과: </h3>

            <button type="button" onClick={handleClick}>클릭미</button>

        </div>
    )
}

'Front-End > React' 카테고리의 다른 글

6. 리액트 기본훅  (0) 2022.12.26
5. 컴포넌트 반복  (0) 2022.12.23
3. 리액트 State  (0) 2022.12.21
2. 리액트의 Components와 props  (0) 2022.12.21
1. 리액트 시작하기  (0) 2022.12.21
  1. 리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미합니다
  2. state가 체인지 되면 변화를 감지하여 리렌더링을 수행합니다.
  3. 클래스 vs 함수형 컴포넌트에서 사용하는 방법이 다릅니다.
  4. 함수형 컴포넌트에서는 훅 Hook개념을 이용해서 더욱 쉽게 사용 가능 합니다.

 

나의 첫번째 훅

useState(초기값) 

useState() : 배열반환 

첫번째 배열의 요소에는 현재값을, 두번째 요소는 상태를 변경하는 (setter) 를 반환합니다.

 

const [data, setData] = useState('초기값')

 

state는 어떤 타입이던 상관 없습니다. (str, number, object)

state는 여러개 일 수도 있습니다.

state는 직접 수정하면 안 됩니다. setter를 사용하세요!

 

const StateComponent = () => {

    const [msg, setData] = useState('초기값')

    const enter = () => setData('입장했습니다')
    const exit = () => setData('퇴장했습니다')

    return (
        <div>
            <h3>{msg}</h3>
            <button onClick={enter}>입장</button>
            <button onClick={exit}>퇴장</button>
        </div>
    )

}

'Front-End > React' 카테고리의 다른 글

6. 리액트 기본훅  (0) 2022.12.26
5. 컴포넌트 반복  (0) 2022.12.23
4. 리액트 이벤트 핸들링  (0) 2022.12.21
2. 리액트의 Components와 props  (0) 2022.12.21
1. 리액트 시작하기  (0) 2022.12.21

1. 컴포넌트

 

리액트의 컴포넌트의 형태 (Tree구조)

 

컴포넌트는 함수형, 클래스형 2가지입니다.

함수형

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

클래스형

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

수업에서는 함수형 컴포넌트를 사용합니다.

 

어떻게???

모듈내보내기 - 외부에서 사용할 모듈 이름을 지정합니다.
- export default 이름 
모듈불러오기 - 부모컴포넌트에서 사용
import 이름 from 경로;

 

컴포넌트 합성

- 예를 들어 Welcome을 여러 번 렌더링하는 App 컴포넌트를 만들 수 있습니다.

//상위
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

//하위
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

2. props (중요)

상위 컴포넌트에서 하위컴포넌트로 전달하는 매개변수 입니다.

 

하위 컴포넌트에서 사용할 때는 {}를 이용해서 값을 받을 수 있습니다.

 

상위 컴포넌트에서는 컴포넌트의 속성값을 동일이름으로 지정합니다.

 

 

//상위
const App = () => {
    return ( 
    	<Fragment>
        	<MyComponent name={"홍길동"} age={2} email={"aa@naver.com"}/>
    	</Fragment>
    )
}

//하위
const MyComponent = ( {name, age, addr, email} ) => {
   return (
        <div>
            나의 첫번째 컴포넌트<br/>
            프로퍼티1:{name}<br/>
            프로퍼티2:{age}<br/>
            기본값 프로퍼티3:{addr}<br/>
        </div>
   )

props의 기본값 설정하기 (주의 - 대소문자 정확하게 구분함  )

컴포넌트명.defaultProps = {}

MyComponent.defaultProps = {
    addr: '서울시',
    age: 0    
}

 

props의 타입검증 (주의 - 대소문자 정확하게 구분함  )

컴포넌트명.propTypes = {}

MyComponent.propTypes = {
    name: PropsTypes.string,
    age: PropsTypes.number,
    email: PropsTypes.string.isRequired //필수값(상위컴포넌트에서 반드시 전달)

}

'Front-End > React' 카테고리의 다른 글

6. 리액트 기본훅  (0) 2022.12.26
5. 컴포넌트 반복  (0) 2022.12.23
4. 리액트 이벤트 핸들링  (0) 2022.12.21
3. 리액트 State  (0) 2022.12.21
1. 리액트 시작하기  (0) 2022.12.21

1. 리액트란?

 

- 리액트는 자바스크립트 라이브러리 입니다.

- 구조가 MVC, MVVM과 같은 다른 프레임워크등과는 다르게 오직 View만 처리하는 라이브러리 입니다.

 

SPA란?

- Single Page Application의 줄임말 입니다.

- index.html하나만 로드하고 실행시키는 구조입니다.

 

어떻게?

번들러(Webpack)가 이 모든것을 해줍니다.

Webpack이란 어플리케이션을 동작시키는데 필요한 자원(JS파일들, CSS, Image 등)을 하나로 묶어서 조합하여 경량화 하여 결과물을 만들어 주는 도구입니다.

번들러는 node.JS를 통해 직접 설정 할 수 있지만, 리액트 프로젝트를 생성시 자동으로 포함됩니다.

 

 

DOM (Document Object Model) 이란?

- HTML을 이해하기 쉽도록 트리 구조로 만들어진 태그(객체)들 입니다

 

리액트의 Virtual DOM 이란?

HTML에서 DOM을 조작하여 처리할 때, DOM핸들링 자체는 빠릅니다.

하지만, 웹 브라우저가 DOM의 변화를 감지하고, CSS를 적용하고, 처리하는 과정에서 시간이 많이 소요됩니다.

 

리액트의 Virtual DOM은, 이를 추상화시킨 자바스크립트 객체를 이용해서, 바뀐 부분만 부분적으로 리렌더링 하여 사용 하는 방법입니다.

 

걱정마세요 리액트가 해줄거에요


2. 환경설정하기

1. node.js 다운. 설치

2. 에디터 vscode 설치

3. create-react-app으로 프로젝트 생성하기

npm create react-app 프로젝트명

4. 프로젝트  시동하기

npm start

 


리액트 코드 살펴보기

1. index.js

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
	<React.StrictMode>
   		<App />
	</React.StrictMode>
);

index.html에 id가 root인 값을 얻습니다


React.StricMode는 옛날 기능을 사용할때 경고를 출력하는 기능입니다(클래스형 컴포넌트)

 

root의 render함수는 App컴포넌트를 화면에 그립니다

 

2. App.js

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

- return (JSX) 문장을 반환합니다.

- export default App 로 모듈을 빼냅니다.

- Index.js 파일에서 <App/> 로 사용됩니다.

 

- JSX란?

JS의 확장 문법으로 (HTML에 JS코드를 녹여낸 형태) 입니다.

 

- 코드를 수정하게 될 때 자동으로 화면이 리렌더링 됩니다. (웹팩 로더가 동작)

- Webpack Loader는 직접 설정(커스터마이징)도 가능하고, create react-app 생성시 자동으로 해줍니다.

Webpack Loader는 다양한 종류가 있습니다.
1. css로더 - css로드
2. file로더 - 폰트,이미지, 파일 등 로드
3. babel로더 - ES6문법을 화면에서 사용할 ES5문법으로 다운그레이드 하여 변환해 줍니다.

 


 

JSX의 문법

  1. JSX의 주석 alt + shift + a
  2. JSX문법 - 반드시 하나의 태그를 return 해야 합니다.
  3. div를 사용하기싫다면 Fragment컴포넌트를 이용하면 됩니다.
  4. 함수안에서 만들어진 변수는  중괄호 {name} 로 참조할 수 있다.
  5. if문 대신 3항연산자를 이용한다.
  6. 화면에 보여주고싶은게 없다면 null을 이용합니다.
  7. undefind을 반환하는 상황을 만들면 안 됩니다. 
  8. DOM요소에 스타일을 직접 넣을때는 반드시 객체형 객체로 묶고 속성은 카멜 표기법을 사용합니다.
  9. class대신 className을 사용합니다.
  10. 홀로 사용하는 태그는 닫는태그를 반드시 작성합니다.

 

'Front-End > React' 카테고리의 다른 글

6. 리액트 기본훅  (0) 2022.12.26
5. 컴포넌트 반복  (0) 2022.12.23
4. 리액트 이벤트 핸들링  (0) 2022.12.21
3. 리액트 State  (0) 2022.12.21
2. 리액트의 Components와 props  (0) 2022.12.21

1. let과 const

  1. let변수는 중복선언이 불가능하다.
  2. let변수의 유효범위는 {}블록이다.
    //let변수는 같은 블록에서 내에서 중복이 불가능하다.
    let y = 1;
    // let y = 100; //에러

    //let변수의 유효범위는 {}블록이다
    let z = 10;
    if(true) {
        let z = 100;
        console.log(z); //100
    }
    console.log(z); //10

 

1. const

	
    const GENDER = "남자";
    // var GENDER = "여자"; //에러
    // GENDER = "여자"; //에러

    const arr = ["홍길동", "이순신", "홍길자"];
    // arr = ["김철수"]; //에러
    arr[0] = "김철수"; //내부의 값 변경은 허용
    arr.push("박영희"); //내부의 갑 변경 허용

    //객체에서의 수정
    const P1 = {"name" : "홍길동" };

    // P1 = {"name" : "이순신"}; //P1을 전부 바꾸는 코드는 에러
    P1.name = "이순신"; //내부의 값의 변경은 허용
    P1.age = 20; //내부의 값의 추가도 허용

2.  spread operator (전개구문)

  1. 반복 가능한(iterable)에 적용할 수 있는 문법입니다.
  2. 배열이나 문자열 등을 아래처럼 풀어서 요소 하나 하나로 전개시킬 수 있습니다.
	
    const arr = [1,2,3];
    console.log(...arr); //num의 요소들을 추출
    
    const str1 = 'hello'; 
    const str2 = [...str1]; 
    console.log(str2); // [ "h", "e", "l", "l", "o"]
	
    //배열에서 전개구문
    //배열의 추가
    const num1 = [10, 20, 30, ...arr];
    console.log(num1)

    //배열의 중간추가
    const num2 = [10, 20, ...arr, 30];
    console.log(num2)

    //배열의 복사
    const num3 = [...arr]; //splice와 유사(복사)
    console.log(num3)

    //배열 연결
    const num4 = [...arr, ...arr]
    console.log(num4)

 

3. 함수에서 spread operator

    const num = [1,2,3];

    //함수의 전달
    function sum(x, y, z) {
        return x + y + z;
    }
    console.log( sum(...num) ); //num의 요소를 x,y,z로 전달
    console.log( sum(10, ...num) ); //10, 1, 2, 3을 전달


    //함수의 매개변수의 사용(가변적 매개변수) - 단 마지막에 작성해야 합니다.
    function sum2(x, ...arr) {
        return [x, ...arr]; //리스트 반환
    }

    console.log( sum2("홍길동", 1) )
    console.log( sum2("홍길동", 1,2) )
    console.log( sum2("홍길동", 1,2,3) )


    //함수의 default매개값
    function sum3(x, y = 10, z = 100) {
        return x + y + z;
    }

    console.log( sum3(1) ) //111
    console.log( sum3(1, 2) ) //103
    console.log( sum3(1, 2, 3) ) //6
    console.log( sum3(...[1,2] )) //1,2를 추출해서 전달 //103

3.  Destructuring assignment (구조 분해 할당)

1. 배열에서 destructuring

 

    let arr = ["홍길동", "이순신", "홍길자", "김철수"];
    /* 기존의 방법
    let n1 = arr[0];
    let n2 = arr[1];
    let n3 = arr[2];
    let n4 = arr[3];
    */

    //위치요소를 반환받아서 한번에 사용한다.
    let [a,b,c,d] = arr;
    console.log(a,b,c,d)

    let [n1, , ,n2] = arr;
    console.log(n1, n2)

    //전부다 반환한다.
    let [...x] = arr;
    console.log(x);

    //남아있는 모든 요소를 반환한다.
    let [k1, k2, ...all] = arr;
    console.log(k1, k2, all)

 

2. 객체에서 destructuring

    let person = {
        "name": "김철수", 
        "age" : 30,
        "job" : ["programmer", "designer"]
    }
	
    //name키 값을 가져온다.
    let {name} = person;
    console.log(name);
    
    let {name, age, job} = person;
    console.log(name, age, job);

    //다른 이름으로 가져오기
    let {name: aaa, age:bbb} = person; //name을 aaa이름으로 가져온다
    console.log(aaa, bbb)

4. for of문

1. 반복 가능한 객체(iterable)를 for문 안에서 반복시켜 연속된 결과값을 얻습니다.

2. forEach문에서 지원하지 않는 break, continue, return의 사용가능

    let arr = ["a", "b", "c"];
    //기존의 for문
    /*
    for(let i = 0; i < arr.length; i++) {
        console.log(arr[i]);
    }
    for(let i in arr) {
        console.log(arr[i]); //i는 인덱스를 담아준다
    }
    */
    
    //기존의 foreach문
    /*
    arr.forEach(function(value, index, arr) { 
        console.log(value);
        console.log(index);
        console.log(arr);
    })
	*/

    //es06 - forof문 (단 list같은 반복가능 요소에만 적용된다)
    for(let i of arr ) {
        console.log(i); //값을 뽑아준다.
    }
    
    //error
    let obj = {name: "g", age: 1};
    for(let i of obj) {
        console.log(i);
    }

5. Backtick 

1. 백틱 `을 용해서 문자열을 표현하고, 템플릿 리터럴 ${}를 이용해서 필요값을 처리

    let name = '홍길동';
    let age = 20;
	//기존문법
    console.log('제 이름은 ' + name + '이고 나이는 ' + age + "입니다");
    //backtick문법    
    console.log(`제 이름은 ${name}이고 나이는 ${age}입니다`);

6. Arrow Function (화살표함수 👍)

1. 화살표 함수는 기본적으로 익명함수를 대체합니다. (호이스팅 불가)

2. 가독성이 향상됩니다.

    //기존익명함수
    /*
    var a = function() {
        console.log('a실행');
    }
    */
    
    //화살표
    let a = () => { 
        console.log('a실행');
    }

 

문법1
코드가 한개줄이면 {} 생략이 가능하다
{}를 쓰지 않으면 기본값으로 undefined를 반환합니다.
{}를 쓰지 않고 구문을 작성하면 리턴문이 됩니다.
    let b1 = (a) => console.log(a); //출력
    console.log( b1(1) ); //undefined

    let b3 = (a, b) => a + b; //리턴문
    console.log( b3(1, 2) ); //3
문법2
매개변수가 1개라면, 매개변수 자리의 ()의 생략이 가능합니다.
    let func = a => a + 10;
    console.log ( func(10) ); //20
문법3
객체를 반환 할때는 ()를 묶어 줍니다.
    //1st
    let c = () => {
        return {key: '홍길동'};
    }
    //2nd
    let d = () => ({key: '이순신'});

화살표 함수의 응용 forEach, filter, map

1. forEach - 반복문

array.forEach(callbackFunction(currenValue, index, array), thisArg) 
  • currenValue: 현재값
  • index: 현재인덱스
  • arrayt: 현재배열,
  • thisArg: callbackFunction 내에서 this로 사용될 값
    //1st
    list.forEach( function(x, y, z) {
        console.log(x, y, z);
    });
    //2nd
    list.forEach( (x,y,z) => console.log(x,y,z) )

2. filter - 요소개수만큼 반복하며 boolean을 이용한 새로운 list를 만듬

array.filter(callbackFunction(currenValue, index, array), thisArg) 
    var result = list.filter( function(x, y, z) {
        return x % 2 == 0; //요소가 true인결과를 반환(요소들의 짝수만 반환)
    });
    console.log(`result: ${result}`);  //2, 4, 6, 8, 10
    
    //2nd
    var result = list.filter( (x, y, z) => x % 2 == 0);

3. map - 실행한 결과를 가지고 새로운 배열을 만들 때 사용

array.map(callbackFunction(currenValue, index, array), thisArg) 
    //1st
    var result2 = list.map( function(x, y, z) {
        return x * x; //처리한 연산결과를 반환
    });
    console.log(`result2: ${result2}`); //1, 4, 9, 16 ... 100

    //2nd
    var result2 = list.map( x => x * x );

4. this키워드의 사용 - 일반함수로만 가능

    let result3 = list.map(function(x) {
        return x % this.value == 0 ? true : false;
    }, {value: 5}); //this가 된다.

    console.log(result3); //f, f, f, f, t ,f, f, f, f, t

7.  class

일반HTML에서는 굳이 class를 사용하진 않습니다. 

React의 class컴포넌트를 사용한다면 알아두세요.

1. 클래스의 멤버변수를 선언할 때는 키워드를 사용하지 않습니다. (구형브라우저에서는 지원불가 할 수 있음)

    class Person {
        //멤버변수 
        name = '홍길동';
        age = 20;

        //객체변수
        state = { 
            a: 1,
            b: () => {
                return 'obj의 b';
            }
        }

        //생성자
        //자바스크립트 생성자는 1개 입니다. (생성자 중복 불가)
        //멤버변수는 선언하지 않더라도 this.변수명을 지칭하면 자동 생성됩니다.
        constructor(addr) {
            this.addr = addr;
        }

        //함수
        func = (a) => {
            return "함수호출";
        }

    }
    
    //객체 생성1
    let p = new Person();

    console.log(p.name) //멤버변수 접근
    console.log(p.age)
    console.log(p.func()); //함수호출한 결과 출력
    console.log(p.state.a); //obj의 a접근
    console.log(p.state.b()); //obj의 b함수 호출한 결과 출력
    
    //객체의 생성2
    let p2 = new Person('서울시');
    console.log(p2.addr); //서울시

클래스 상속

    class Shape {
        constructor() {}
    }

    class Rect extends Shape {
        //생성자 자체는 생략가능
        constructor(w, h) {
            super(); //반드시 연결
            this.w = 20;
            this.h = 10;
        }    

        /* set */ setW(w) {
            this.w = w;
        }
        setH(h) {
            this.h = h;
        }     

        /* get */ getArea() {
            return this.w * this.h
        }

        // get, set, static 예약어로 메서드를 설정할 수 있음
    }

    //객체생성
    let rect = new Rect();
    console.log(rect.getArea())	// 200

    rect.setH(100);	
    rect.setW(20);
    console.log(rect.getArea())	// 2000

 

8. module import export

* 모듈 임포트

- 모듈은 JS ES6문법에서 미리 작성해 놓은 스크립트 파일이며, 모듈 안에는 변수, 함수, 클래스 등이 정의되어 있습니다.

- ES6부터는 주요기능들을 모듈로 구성하여 사용이 가능합니다.

- 모듈을 내보내는 방법은 named export방식과 default export방식 2개가 있습니다.
- 여러 값을 내보낼 때 named export방식
- 단일 값을 내보낼 때 default export방식

script01.js

//내보내기 1
export const name = '홍길동';
export const age = 20;

export const getInfo = () => {
    console.log('이름:', name, '나이:', age);
}

//내보내기2
let sum = 0;
let add = (x) => {
    sum += x;
    console.log(sum);
}

export {sum, add}; //선언해논 변수를 export{} 로 내보내기

script01.html

  • HTML5파일에서 예외적으로 module을 사용할려면 type="module" 문을 반드시 작성합니다.
<script type="module">
    //HTML5표준에서 예외적으로 module을 사용할려면 type="module" 문을 반드시 작성합니다.

    //import방법1 (Destructuring방식)
    import {name, age, getInfo} from './script01.js';

    console.log(name);
    console.log(age);
    getInfo(); 

    //import방법2 (Alias방식)
    import * as test from './script01.js';
    
    console.log(test.name);
    console.log(test.age);
    test.getInfo();
    console.log(test.sum);
    test.add(10);

    //import방법3 (이름바꿔 가져오기);
    import {name as n, age as a, getInfo as get} from './script01.js';
    
    console.log(n);
    console.log(a);
    get();


</script>

 

 

하나의 모듈에서 하나의 객체를 이름으로 내보낼 때 단일 객체 내보내기 export default문을 사용합니다.

Class나 함수를 내보낼떄는 세미콜론을 붙이지 않도록 권유됩니다.

script02.js

class Person {

    constructor(name, age) {
        this.name = name;
        this.age = age;
    }    

    getInfo = () => {
        return '이름:' + this.name; 
    }

}

export default Person

script02.html

<script type="module">
    //import방법 4
    import Person from './script03.js';

    //클래스 import로 객체 생성문이 필요합니다.
    let park = new Person('홍', 20);
    console.log(park.name);
    console.log(park.age);

</script>

 

'Front-End > JavaScript(ES6)' 카테고리의 다른 글

JS ES6 문법 Promise, async, await  (0) 2022.12.30

출처

https://heropy.blog/2018/11/24/css-flexible-box/

 

CSS Flex(Flexible Box) 완벽 가이드

많은 경우 float, inline-block, table 등의 도움을 받아서 수평 레이아웃을 구성하지만 이는 차선책이며, 우리는 Flex(Flexible Box)라는 명확한 개념(속성들)으로 레이아웃을 쉽게 구성할 수 있습니다. CSS F

heropy.blog

























'Front-End > HTML & CSS' 카테고리의 다른 글

5. FLEX기초문법  (0) 2022.06.23
3. CSS기초문법1(선택자, font, border, text속성)  (0) 2022.06.23
2. HTML태그  (0) 2022.06.23
1. HTTP통신과 웹  (0) 2022.06.23










 

'Front-End > HTML & CSS' 카테고리의 다른 글

5. FLEX기초문법  (0) 2022.06.23
4. CSS기초문법2(display, background, padding-margin, box-sizing, float, position)  (0) 2022.06.23
2. HTML태그  (0) 2022.06.23
1. HTTP통신과 웹  (0) 2022.06.23














- 웹이란 1개 이상의 사이트가 연결되어 있는 인터넷 서비스의 한가지 형태입니다.

- 인터넷이란 1개 이상의 네트워크가 연결되어 있는 형태를 말합니다.

 

 


인터넷 서비스의 구분

* URL

http://192.110.32.11:8080/

  1. 프로토콜(protocol): 네트워크상에서 약속한 통신규약 (HTTP, FTP, SMTP, POP, DHCP)
  2. IP주소: 네트워크상에서 특정 컴퓨터를 식별할 수 있는 주소
  3. Port 번호: IP주소가 컴퓨터를 식별할 수 있게 해준다면, 포트번호는 해당 컴퓨터의 구동되고 있는 프로그램을 구분할 수 있는 번호.
  4. DNS(도메인): IP주소를 인간이 쉽게 외우도록 맵핑한 문자열.

 


웹어플리케이션과 웹서버


웹표준

  • 같은 문법이라도 브라우저 별로 달리 구현되는 기술을 동일하게 구현할 필요가 있었다.
  • 브라우저에 따라 달리 구현되는 기술을 동일하게 구현함과 동시에 어느 한쪽에 최적화되어 치우치지 않도록 공통요소를 사용하여 웹 페이지를 제작하는 기법이 웹표준 이다.
  • W3C(World Wide Web Consortium) 재단에서는 웹 표준을 제정
 
 

HTML 5 표준

  • 2009년에 W3C 재단과 마이크로소프트가 함께 제정하던 XHTML 2.0 표준이 붕괴하면서 대체안으로 Web Application 1.0 표준을 사용
  • Web Application 1.0 표준을 현재 HTML5 표준이라고 부름

 

+ Recent posts