반응형

과거 1년전쯔음에 만들었던 프로젝트가 있었는데 CRA로 생성한 프로젝트였다. 

 

Refactor를 위해 javascirpt에서 typescirpt로 바꾸고  React-query를 설치하려고 했는데 npm i 에서 에러가 났다. 

 

react-script 패키지가 'typescript@4.x'를 요구하는것이다. 

메세지에 --legacy-peer-deps옵션을 사용하는 방법이 있고 --force하는 방법도 있는데 두 방법 호환성을 억지로 맞추거나 아니면 보안에 취약한 선택인거 같아 첫째론 CRA github페이지에 들어가 보았다. 최신 commit이 작년이여서 방도를 몰라 GPT에게 물어본 결과 NEXT나 webpack 혹은 Vite를 사용하라는 결과가 나왔다. 

 

기존 작업해 둔 것들이 있고 데이터베이스를 따로 사용하지 않아 Next로 바꾸는 것은 아닌것 같고 webpack으로 설정하면 너무나도 많은 설정이 있어 복잡해질것을 우려가 되어 빠르고 업그레이드 할 수 있는 Vite로 해결하는 것이 옳다고 판단이 들어 Vite를 설치 했다.

https://ko.vitejs.dev/

 

Vite

Vite, 차세대 프런트엔드 개발 툴

ko.vitejs.dev

Install

npm install vite

 

vite 설치 후 프로젝트의 파일경로들을 조금 수정하고 몇가지 파일도 생성을 해주어야 한다. 일단 파일경로를 살펴보면

 

CRA로 생성한 index.html은 public 폴더에  생성되는데 이 파일을 프로젝트 ROOT에 옮겨준다.

다음은 index.html에 있는 내용을 수정해주어야하는데 public에 관련된 파일 경로 (%PUBLIC_URL%)작성을 지워준다.

또한 body tag안에 script를 추가해 react가 시작되는 파일을 불러와주어야한다.

폴더경로
========
|public/
-| img/
--| main/
---| horse_icon_16.png
-| favicon.ico
-| manifest.json
|src
.
.
.
========

html 내부
========
<link rel="icon" href="/img/main/horse_icon_16.png" />

<body>
    <div id="root"></div>
    <script type="module" src="/src/index.tsx"></script>
</body>

vite.config.ts

다음 단계는 vite 설정파일을 만들어주는 것이다. 파일이름은 vite.config.ts이며 root에 위치해야한다.

그리고 인텔리센스 설정을 해준다. https://ko.vitejs.dev/config/#config-intellisense

 

Vite

Vite, 차세대 프런트엔드 개발 툴

ko.vitejs.dev

그리고 vite에서 react를 사용할 수 있게 plugin을 지정해준다.

server host를 원하는 번호로 입력해준다. 프록시 , cors, headers 등을 더 알고 싶으면 위 링크.

import {defineConfig} from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
  },
});

 

Environment Variables

CRA에서 env를 사용하기 위해서는 root에 .env 파일 내부에 REACT_APP_**이라고 변수를 만들어주어서 스크립트 내부에 

process.env.REACT_APP_**라고 생성했었다. 하지만 vite에서는 process.env를 사용하기 위해서는 .env파일에 VITE_APP_***라고 생성해야며 사용시에는 import.meta.env.VITE_APP_***으로 사용되어야한다. 또한 typescript를 사용해 자동완성을 만들기 위해서는  src 폴더내에 vite-env.d.ts를 만들어 사용한다.

// src/vite-env.d.ts

/// <reference types="vite/client"/>

interface ImportMetaEnv {
  readonly VITE_APP_OPEN_API_ENCODING_KEY: string;
  readonly VITE_APP_API_KEY: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

 

728x90

'React > ReactJS' 카테고리의 다른 글

2023/07/27__ReactJS(5)  (0) 2023.07.27
2023/07/24__ReactJS(4)  (0) 2023.07.24
2023/07/21__ReactJS  (0) 2023.07.21
2023/07/20__ReactJS(3)  (0) 2023.07.20
2023/07/19__ReactJS(2)  (0) 2023.07.19
반응형

getContent(App.js)

getContet()

  • render()내에 길고 복잡한 문장을 getContent()함수로 분리
  • getContent()에서는 필요한 data를 return으로 전달
  • return : 함수내의 값을 함수 밖으로 전달
  • render()에서는 this.getContent()로 함수 내의 코드 로드

Router

기존 렌더링 호출 함수 및 작성 코드 수정

import ReactDOM from 'react-dom' 

변경된 작성 코드

import ReactDOM from 'react-dom/client'

 

BrowserRouter 사용하기(App.js)

BrowserRouter,Router,Route 컴포넌트 작성

  • BrowserRouter :UI의 최상위에 작성
  • Routes : Route set
  • Route: 링크 설정

path,element 컴포넌트 작성

  • path : 브라우저에 출력될 주소
  • element : 화면에 출력될 컴포넌트

Link 작성

  • <a>요소 사용하려면 페이지가 reload
  • <Link>를 사용하여 페이지 reload없이 <a> 요소와 같은 효과 사용
  • <Link>클릭할 콘텐트 </Link>

to 속성 작성

  • <Link to='<Route>의 path 속성값'> 클릭할 콘텐트 </Link>
//app.js
import "./App.css";
import {BrowserRouter, Routes, Route, NavLink, Link} from "react-router-dom";
import Contact from "./components/Contact";
import Home from "./components/Home";
import Topics from "./components/Topics";
import Notfound from "./components/Notfound";

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">
          <h1>Welcome!!!</h1>
        </Link>
        <nav>
          <ul>
            <li>
              <NavLink to="/Topics">토픽</NavLink>
            </li>
            <li>
              <NavLink to="/Contact">콘텍트</NavLink>
            </li>
          </ul>
        </nav>
        <Routes>
          <Route index element={<Home />}></Route>
          <Route path="/Topics/*" element={<Topics />}></Route>
          <Route path="/Contact" element={<Contact />}></Route>
          <Route path="/*" element={<Notfound />}></Route>
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;

//home.js
export default function Home() {
  return (
    <div>
      <h2>HOME</h2>
    </div>
  );
}


//Topics.js
import {NavLink, Routes, Route, useParams} from "react-router-dom";
import Notfound from "./Notfound";

const contents = [
  {id: 1, title: "HTML", comp: <Topics1 />},
  {id: 2, title: "JS", comp: <Topics2 />},
  {id: 3, title: "React", comp: <Topics3 />},
];
function Topic() {
  const param = useParams();
  const topic_id = Number(param.Topic_id);
  let selected_comp = <Notfound />;
  for (let i = 0; i < contents.length; i++) {
    if (topic_id === contents[i].id) {
      selected_comp = contents[i].comp;
      break;
    }
  }
  // console.log(param);
  // console.log(topic_id);
  // if (topic_id == 1) {
  //   selected_comp = <Topics1 />;
  // } else if (topic_id == 2) {
  //   selected_comp = <Topics2 />;
  // } else if (topic_id == 3) {
  //   selected_comp = <Topics3 />;
  // } else {
  //   selected_comp = <Notfound />;
  // }

  return <div>{selected_comp}</div>;
}

export default function Topics() {
  const list = [];
  for (let i = 0; i < contents.length; i++) {
    list.push(
      <li key={contents[i].id}>
        <NavLink to={"Topics/" + contents[i].id}>{contents[i].title}</NavLink>
      </li>
    );
  }
  return (
    <div>
      <h4>Topics</h4>
      <nav>
        <ul>{list}</ul>
      </nav>
      <Routes>
        <Route path="Topics/:Topic_id" element={<Topic />}></Route>

        {/* <Route path="Topics/2" element={<Topics2 />}></Route>
        <Route path="Topics/3" element={<Topics3 />}></Route>
        <Route path="Topics/*" element={<Notfound />}></Route> */}
      </Routes>
    </div>
  );
}

function Topics1() {
  return (
    <div>
      <h2>t1</h2>
    </div>
  );
}
function Topics2() {
  return (
    <div>
      <h2>t2</h2>
    </div>
  );
}
function Topics3() {
  return (
    <div>
      <h2>t3</h2>
    </div>
  );
}



// contact.js
export default function Contact() {
  return (
    <div>
      <h6>Contact</h6>
    </div>
  );
}



//app.css
/*
a {
  text-decoration: none;
  color: cornflowerblue;
}
.active {
  color: tomato;
}

*/

배열과 반복문 파라미터 활용

배열과 반복문 활용하여 라우팅 작성

  • 모듈가져오기
  • import {useParams} from "react-router-dom"
728x90

'React > ReactJS' 카테고리의 다른 글

Upgrade CRA to VITE(React)__001  (1) 2024.07.15
2023/07/24__ReactJS(4)  (0) 2023.07.24
2023/07/21__ReactJS  (0) 2023.07.21
2023/07/20__ReactJS(3)  (0) 2023.07.20
2023/07/19__ReactJS(2)  (0) 2023.07.19
반응형

함수 방식 라이프사이클 구현

16.8 이후 버전에서 hook 사용하여 구현가능

  • useEffect

useEffect

  • useEffect = side effect : 부가 작용(after function) //  EX) $('').slideUp(delay,function(){})
  • 함수형 컴포넌트 (function)의 내에 작성하지만 retrun 내의 코드가 실행(render)된 이후에 동작
  • 하나의 함수형 컴포넌트 안에 여러 개의 useEffect 설치 가능
  • 첫 번째 인자에는 함수 작성
  • class 방식의 componentDidMount, componentDidUpdate와 동일

clean up(정리)

  • componentWillMount, render, componentDidMount : 컴포넌트가 처음으로 DOM에 나타나는 순간에 수행해야 할 초기 작업 구현
  • componentWillUnmount : 컴포넌트 퇴장 또는 소멸 시 수행해야 할 작업 구현

useEffect를 이용한 clean up

  • useEffect의 첫 번째 인자인 function 함수 안에 return 함수 사용
  • useEffect 실행 후 반환될 내용 작성

clean up을 이용한 useEffect

  • 초기 실행 : render - useEffect
  • 재실행 : render - return - useEffect
const funcStyle = "color:white; background:tomato";
let funcId = 0;

useEffect(() => {
    console.log("%cfunc=> useEffect is complete" + ++funcId, funcStyle);
    return function () {
      console.log(
        "%cfunc=> useEffect return is complete" + ++funcId,
        funcStyle
      );
    };
  });

skipping Effect(Effect를 건너뛰어 성능 최적화하기)

  • 성능을 최적화하기 위해 Effect가 호출되는 것을 생략하는 기법

class 방식 Skipping Effect

  • componentDidUpdate함수의 인자로 이전 props 값과 이전 state를 가져온 후 현재 state값과 이전 state값이 다른 경우에만 문장실행
componentDidUpdate(prevProps,PrevState){
 if(prevState.count !== this.state.count){
 	document.title = `you clicked ${this.state.count} times`;
 	}
 }

함수 방식 Skipping Effect 

  • useEffect 함수의 두번째 인자에 비교할 값을 배열 형태로 입력하여 사용
useEffect(()=>{
  document.title = `you Clicked ${count} times`;
  }, [count]);
  
  //count가 바뀔 때만 effect를 재실행 합니다.

useEffect 실행 활용

  • useEffect는 컴포넌트 라이프 사이클 중  componentDidMount와 componentDidUpdate에 해당하는 타이밍에 실행되므로 2번 실행됨

componentDidMount 일 때에만 실행하기

  • 두번째 인자의 배열값을 빈 값으로 입력
  • 컴포넌트가 생성될 때 처음 1회만 실행되고 이후에는 실행되지 않음
  • useEffect 함수 내에 return 함수는 componentWillUnmount와 동일한 효과 발생

 

 

728x90

'React > ReactJS' 카테고리의 다른 글

Upgrade CRA to VITE(React)__001  (1) 2024.07.15
2023/07/27__ReactJS(5)  (0) 2023.07.27
2023/07/21__ReactJS  (0) 2023.07.21
2023/07/20__ReactJS(3)  (0) 2023.07.20
2023/07/19__ReactJS(2)  (0) 2023.07.19
반응형

Class 스타일 컴포넌트 vs 함수 스타일 컴포넌트 

클래스 문법 사용

  • 리액트 기능 100%활용
  • 클래스 문법에 대한 이해 필요
  • 많은 자료가 클래스 문법으로 작성

함수 문법 사용

  • 기능부족
  • 함수 문법만 알면 사용가능
  • 컴포넌트 내부에 state사용불가
  • life cycle API사용불가(컴포넌트 생성, 수정, 삭제 관련이벤트)
  • 현재는 HOOK 도입으로 class 정도의 성능 지원(React 16.8 이상)

클래스에서 prop 사용하기

  • 컴포넌트 제작 시 prop명 ={값}으로 작성
  • 컴포넌트 사용시 {this.props.props이름}으로 출력

함수 방식으로 props사용하기

  • 컴포너트 제작 시 props명={값}으로 작성
  • 함수명에 매개변수 작성
  • 컴포넌트 사용 시 {매개변수명.props명}으로 출력
  • this는 클래스 방식에서 사용, 함수방식에선느 사용하지 않으므로 삭제

클래스에서 state 사용하기

  • state에 props를 전달하여 사용
  • render()함수 외부에 작성
  • state = {state명:값 , state명:값,...} <--state 초기화
  • {this.state.state명} 으로 사용
  • state 값이 바뀔 때 마다 클래스 컴포넌트의 render()실행
  • state는 render의 밖에 꼭 두어야한다

함수 방식으로 state 사용하기

  • hook을 사용
  • React 내장 hook, 사용자 정의 hook 가능
  • hook의 이름은 'use'로 시작
  • useState : 페이스북이 제공하고 있는 내장 hook의 이름

useState

  • 페이스북이 제공하고 있는  내장 hook의 이름
  • 현재의 state값과 이 값을 업데이트하는 2개의 값을 배열 형태로 제공
  • 첫 번째 값에 사용하고자 하는 값 리턴 <--state의 초기값
var 리턴받을 함수 = useState(props.props이름) // props의 값이 리턴
var 리턴받을 변수 = useState(5); // 5가 리턴
  • 두 번째 값에 상태 변경 여부 작성, 또는 변경될 값 작성
  • class의 this.setState와 유사하지만 이전 state와 새로운 state를 합치지 않음
  • 기존값과 변경된 값이 따로 저장된다.
  • useStata[0] 기존 state값
  • useState[1] 변경할 state 값
const numberState = useState(3)

let number = numberState[0]
let setNumber = numberState[1]

// const [number , setNumber] = useState() => 축약

React라이프사이클

1. componentDidMount - 생성할 때

2. componentDidUpdate - 업데이트할 때

3. componentWillUnMount - 제거 할 때

 

클래스 방식 라이프사이클 구현

componentWillMount

  • constructor 이후 실행
  • render() 이전에 실행되는 함수

render

  • componentWillMount 이후 실행

componentDidMount

  • 화면이 그려진 후 (render)실행할 내용 작성

shouldComponentUpdate

  • state가 변경 되었을 때  render()실행 여부 결정
  • state가 변경되었어도 변경을 안하게 지정할 수 있음

componentWillUpdate

  • state값이 변경되어 render되기 전에 실행할 내용 작성

componentDidUpdate

  • state값이 변경되어 화면에 그려진 이후에 실행할 내용 작성

16.x 버전에서 라이프사이클 함수 자제 권고

  • 17버전부터 componentWillMount 대신 UNSAFE_접두사 추가 또는 constructor로 사용
  • componentWillReceiveProps 대신 UNSAFE_접두사 추가
  • componentWillUpdate 대신 데이터 조회 시 UNSAFE_접두사 추가 또는 componentDidUpdate 사용

렌더링 과정

  • constructor
  • componentWillMount
  • render
  • componentDidMount
  • shouldComponentUpdate
  • componentWillUpdate
  • componentDidUpdate
  • componentWillUnmount
728x90

'React > ReactJS' 카테고리의 다른 글

2023/07/27__ReactJS(5)  (0) 2023.07.27
2023/07/24__ReactJS(4)  (0) 2023.07.24
2023/07/20__ReactJS(3)  (0) 2023.07.20
2023/07/19__ReactJS(2)  (0) 2023.07.19
2023/07/18__React_1  (0) 2023.07.18
반응형

bind 메소드

bind 메소드

  • bind()메소드가 호출되면 새로운 함수를 생성
  • 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드 된 함수의 인수에 제공
//in JSX

const obj = {name:'hellow'}

function bindTest(){
	console.log(this.obj)
    }.bind(this)
    
    bindTest()

에러발생

  • this 객체를 함수 밖에서 생성하여 함수 내부로 바인딩 하더라도 react는 내용이 바뀌었는지 인식불가
  •  
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: "welcome",
      subject: {title: "WEB", sub: "World Wide Web"},
      welcome: {title: "welcome", sub: "Hellow React"},
      contents: [
        {id: 1, title: "html", desc: "HTML is for infromation"},
        {id: 2, title: "css", desc: "css for design"},
        {id: 3, title: "javascrip", desc: "javascript is interactive"},
      ],
    };
  }

  render() {
    console.log("App.js 완료");
    let _title,
      _sub = null;

    if (this.state.mode === "welcome") {
      _title = this.state.welcome.title;
      _sub = this.state.welcome.sub;
    } else {
      _title = this.state.contents[0].title;
      _sub = this.state.contents[0].desc;
    }

    return (
      <div className="App">
<h1>
          <a
            href="#none"
            onClick={function (e) {
              e.preventDefault();
              this.state.mode = 'read'
            }.bind(this)}
          >
            {this.state.subject.title}
          </a>
        </h1>

//작동하지 않음

해결방법

  • setState() 함수사용
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: "welcome",
      subject: {title: "WEB", sub: "World Wide Web"},
      welcome: {title: "welcome", sub: "Hellow React"},
      contents: [
        {id: 1, title: "html", desc: "HTML is for infromation"},
        {id: 2, title: "css", desc: "css for design"},
        {id: 3, title: "javascrip", desc: "javascript is interactive"},
      ],
    };
  }

  render() {
    console.log("App.js 완료");
    let _title,
      _sub = null;

    if (this.state.mode === "welcome") {
      _title = this.state.welcome.title;
      _sub = this.state.welcome.sub;
    } else {
      _title = this.state.contents[0].title;
      _sub = this.state.contents[0].desc;
    }

    return (
      <div className="App">
<h1>
          <a
            href="#none"
            onClick={function (e) {
              e.preventDefault();
              this.setState({mode: "read"});
            }.bind(this)}
          >
            {this.state.subject.title}
          </a>
        </h1>

 

컴포넌트 이벤트

onChangePage 이벤트 생성

  • 페이지가 바뀌었을 때 설치한 함수 호출
  • props 형태로 다른 컴포넌트에 전달 됨
  • 상위에서 하위로 데이터 전달시 props를 사용한다.
  • 하위에서 상위로 전달하려면 이벤트로 전달해야한다. 하위에서 필요한 이벤트를 상위에서 만들고 상위에서 하위에게 이벤트를 전달
  •  
//App.js

import React, {Component} from "react";

import "./App.css";
import Subject from "./components/Subject";
import TOD from "./components/TOD";
import Content from "./components/Content";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: "welcome",
      subject: {title: "WEB", sub: "World Wide Web"},
      welcome: {title: "welcome", sub: "Hellow React"},
      contents: [
        {id: 1, title: "html", desc: "HTML is for infromation"},
        {id: 2, title: "css", desc: "css for design"},
        {id: 3, title: "javascrip", desc: "javascript is interactive"},
      ],
    };
  }

  render() {
    console.log("App.js 완료");
    let _title,
      _sub = null;

    if (this.state.mode === "welcome") {
      _title = this.state.welcome.title;
      _sub = this.state.welcome.sub;
    } else {
      _title = this.state.contents[0].title;
      _sub = this.state.contents[0].desc;
    }

    return (
      <div className="App">
        <h1>
          <a
            href="#none"
            onClick={function (e) {
              e.preventDefault();
              this.setState({mode: "read"});
            }.bind(this)}
          >
            {this.state.subject.title}
          </a>
        </h1>
        <h1>{this.state.subject.sub}</h1>
        <hr />
        <Subject title={_title} sub={_sub} />
        <hr />
        <Subject
          title={this.state.subject.title}
          sub={this.state.subject.sub}
          onChangePage={function (e) {
            this.setState({mode: "read"});
          }.bind(this)}
        />

        <hr />
        <TOD
          hohoho={function () {
            this.setState({mode: "welcome"});
          }.bind(this)}
          data={this.state.contents}
        />

      </div>
    );
  }
}

export default App;


//subject.js

import React, {Component} from "react";

class Subject extends Component {
  render() {
    return (
      <header>
        <h1>
          <a
            href="#none"
            onClick={function (e) {
              e.preventDefault();
              this.props.onChangePage();
            }.bind(this)}
          >
            {this.props.title}
          </a>
        </h1>
        <p>{this.props.sub}</p>
      </header>
    );
  }
}

export default Subject;



// TOD.js

import {Component} from "react";

class TOD extends Component {
  render() {
    const list = [];
    const data = this.props.data;

    for (let i = 0; i < data.length; i++) {
      list.push(
        <li key={data[i].title}>
          <a
            href={"content/" + data[i].id}
            onClick={function (e) {
              e.preventDefault();
              this.props.hohoho();
            }.bind(this)}
          >
            {data[i].title}
          </a>
          <p>{data[i].desc}</p>
        </li>
      );
    }
    return (
      <nav>
        <ul>{list}</ul>
      </nav>
    );
  }
}

export default TOD;

 

728x90

'React > ReactJS' 카테고리의 다른 글

2023/07/27__ReactJS(5)  (0) 2023.07.27
2023/07/24__ReactJS(4)  (0) 2023.07.24
2023/07/21__ReactJS  (0) 2023.07.21
2023/07/19__ReactJS(2)  (0) 2023.07.19
2023/07/18__React_1  (0) 2023.07.18
반응형

State

props

  • 부모 컴포넌트가 자식 컴포넌트에 값을 전달할 때 사용(읽기 전용)

state

  • 컴포넌트 자신이 가지고 있는 값
  • 컴포넌트 내부의 동적 데이터
  • 변화가 필요한 경우 setState()함수 사용

Constructor 작성

class App extends Component{
	constructor(props){ // method bind을 하거나 state를 초기화
    	super(props); //super를 사용해야 this가 사용된다.
        this.state={
        	subject:{title:'WEB', sub:'World Wide Web!'}
        }
   }
   render(){
   	....
   }
}

Constructor(생성자)

  • state(컴포넌트 상태) 값을 초기화하거나 메서드를 바인딩 할 때 사용
  • 해당 컴포넌트가 마운트 되기 전 호출
  • 함수방식에서는 사용불가

마운트

  • DOM 객체가 생성되고 브라우저에 나타나는 것을 의미

컴포넌트 라이프 사이클

  • 마운트 : DOM 객체 생성, 브라우저에 출력
  • Update : props값 변경, state 값 변경, 부모 컴포넌트 리렌더링
  • UnMount : 컴포넌트가 DOM에서 제거

메서드 바인딩

  • 클래스와 메서드 간의 연관 관계
  • 클래스와 연관된 메서드는 클래스에 바인딩 가능

super

  • React.Componet를 상속한 컴포넌트의 생성자를 구현할 때 다른 구문 앞에  super(props)를 호출하지 않으면 this.props가 생성자 내에서 정의 되지 않아 버그 발생

javascript에서의 super

  • 부모 클래스 생성자
  • constructor에서 super(props) 선언 전까지 this 사용 불가

Key props(여러 개의 데이터 사용)

//App.js
import {Component} from "react";

class App extends Component{
	constructor(props){ // method bind을 하거나 state를 초기화
    	super(props); //super를 사용해야 this가 사용된다.
        this.state={
        	subject:{title:'WEB', sub:'World Wide Web!'}
            contents:[
            	{id:1, title:'html', desc:'HTML is for infromation'},
                {id:2, title:'css', desc:'css for design'},
                {id:3, title:'javascrip', desc:'javascript is interactive'}
             ]
        }
   }
   render(){
		return{
        	<TOD data={this.state.contents} />
            }
   }
}



//TOD.js
import {Component} from "react";

class TOD extends Component {
  render() {
    const list = [];
    const data = this.props.data;
    let i = 0;
    for (; i < data.length; i++) {
      list.push(<li>{data[i].title}</li>);
      list.push(<li>{data[i].desc}</li>);
      list.push(<br />);
    }
    return (
      <nav>
        <ul>{list}</ul>
      </nav>
    );
  }
}

export default TOD;

이벤트

이벤트 state props와 render 함수

render 함수

  • react에서는 props나 state가 변경될 때마다 해당되는 컴포넌트의 render 함수 및 하위 컴포넌트의 render함수 호출

 

렌더링 테스트

  • App.js / Subject.js / TOD.js / Content.js 파일에 콘솔로그 작성 후 페이지 실행
  • [개발자 도구] - [콘솔] 탭에서 로그 확인

 

App.js

render(){
	console.log('App.js 렌더링 완료')
    }

이벤트 사용

  • mode 항목 작성하고 welcome일 때 사용할 데이터 추가
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: "welcome",
      subject: {title: "WEB", sub: "World Wide Web"},
      welcome: {title: "welcome", desc: "Hellow React"},
      contents: [
        {id: 1, title: "html", desc: "HTML is for infromation"},
        {id: 2, title: "css", desc: "css for design"},
        {id: 3, title: "javascrip", desc: "javascript is interactive"},
      ],
    };
  }
	render(){
    ....
    }
}

이벤트 작성

  • 요소에 직접 핸들러 작성 후 함수 작성
  • 다른 컴포넌트에 있는 링크로 현재 컴포넌트의 제어 방식 다름(*)
  • 현재 컴포넌트에 링크 사용 이해 후 다른 컴포넌트의 링크 사용 실습

javascript 이벤트 사용

  • onclick = '함수명'

react 이벤트 사용

  • react에서는 유사 html 사용(react 문법 준수)
  • onClick = {실행할 문장}
  • 이벤트 이름은 반드시 대문자 사용

링크에 이벤트 적용

  • 페이지 새로고침
  • 리액트의 장점 - 새로고침 없이 페이지 처리

해결방법

  • 이벤트를 실행한 객체 (요소, 태그)의 기본 동작을 제한
  <h1>
          <a
            href="#none"
            onClick={function (e) {
              alert("Hi!!!");
              e.preventDefault();
            }}
          >
            {this.state.subject.title}
          </a>
        </h1>
728x90

'React > ReactJS' 카테고리의 다른 글

2023/07/27__ReactJS(5)  (0) 2023.07.27
2023/07/24__ReactJS(4)  (0) 2023.07.24
2023/07/21__ReactJS  (0) 2023.07.21
2023/07/20__ReactJS(3)  (0) 2023.07.20
2023/07/18__React_1  (0) 2023.07.18
반응형

리액트 (React) 살펴보기

리액트

  • 페이스북에서 만든 자바스크립트 UI 라이브러리
  • 컴포넌트(사용자 정의태그)를 사용하여 가독성 및 재사용성 향상
  • https://reactjs.org

툴 체인(Tool Chain)

  • 리액트 프로젝트 개발 시 목표에 따라 필요한 여러 가지 개발 환경 및 도구를 모아 한번에 제공하는 도구

리액트 설치

  1. npm i create-react-app
  2. create-react-app -V 설치 확인

npm VS npx

  1. npm : 프로그램설치
  2. npx :해당 프로그램을 한번만 설치 후 자동 삭제
  3. 컴퓨터 공간 낭비 방지
  4. 설치시 마다 새로 다운로드 받기 때문에 항상 최신 상태 유지

프로젝트 생성 명령 입력

디렉토리명으로 react 사용불가

create-react-app [프로젝트명]

create-react-app . (마침표)(현재 디렉토리에 설치)

 

코드 변경 실습

public 디렉토리

수정하지 않음

 

publick > index.html

  • 코드 중간  <div id='root'></div>에 앱 작성 코드 출력
<body>
	<noscript> You need to enable JavaScript to run this app. </noscript>
    <div id='root'></div>
  • 수정 가능하며 수정시 'src/index.js' 파일 코드 수정
  • index.js: 앱의 진입점 역할
const root = ReactDOM.createRoot(document.getElementById('root'));

src > index.css

  • 문서전체

src > App.css

  • App.js안에 작성된 컴포넌트 디자인

배포하기

  • 개발된 앱을 실제 웹이나 모바일에서 사용할 파일로 변환 -- 컴파일
  • 불필요한 코드 삭제로 파일 용량 경량화

빌드된 파일 실행

  • build 디렉토리의 파일 실행
  • -s:build 디렉토리를 루트로 지정

 

안되는 경우 2가지

  • 윈도우 - powshell
  • npm i -g serve를 안해줬거나

컴포넌트

함수방식 컴포넌트

function Name(){
	return(
    	내용
    )
}

클래스 방식 컴포넌트

  • 컴포넌트 이름은 반드시 대문자로 시작
  • render 함수 
  • 자바스크립트 최신 스펙에서는 class 문법에서 function 생략
import React {Component} from 'react'

class Name extends Component {
	 render(){
    	 return(
        	 내용
        )
    }
}
// return
// 출력할 내용작성
// 컴포넌트 만들 때 최상위 디렉토리는 반드시 1개 이어야 함 (1개 요소만 리턴 가능)

App.js

  • 사용자 정의 컴포넌트
  • 유사 자바스크립트(순수 자바스크립트(x))
  • 코드를 쉽게 작성할 수 있도록 JSX언어 사용

JSX(Javascript XML)

  • 자바스크립트 코드 작성 시 따옴표 사용 등 까다로운 문법을 쉽게 작성
  • 메타(페이스북)에서 만든 언어
  • JSX로 코드 작성 시 Create React App 이 자바스크립트 코드로 변환

 

컴포넌트 파일 분리하기

클래스 로딩(component > name.js)

리액트 코딩 시 필수 코드

import React , {Component} from 'react

 

export (component > name.js)

import 할 파일의 변수나 함수 등을 외부에서 사용할 수 있도록 허용

export default TOC

 

파일 호출(App.js)

App.js 파일 상단에 외부에서 가져올 파일 import

import TOC from './component/TOC'

Props 와 State

Props

html : < element attribute = ' value '
react , vue : < Compoment props = 'variable'

State

vue - vuex
react - redux

html의 속성 (attribute)

  • https://reactjs.org/docs/components-and-props.html
  • 같은 태그 (또는 컴포넌트)라도 다르게 사용 가능 - 재사용성 향상

 

728x90

'React > ReactJS' 카테고리의 다른 글

2023/07/27__ReactJS(5)  (0) 2023.07.27
2023/07/24__ReactJS(4)  (0) 2023.07.24
2023/07/21__ReactJS  (0) 2023.07.21
2023/07/20__ReactJS(3)  (0) 2023.07.20
2023/07/19__ReactJS(2)  (0) 2023.07.19

+ Recent posts