정리정돈 개발블로그~
[57일차] 국비 교육 본문
<리액트>
월화수 -> 리액트 학습
목금 -> js 작업 한 것을 리액트로 변환
[리액트]
- MVC 아키텍처 : model, view, controler
- 리액트 디자인패턴 없음
- view만 신경쓰는 라이브러리
- 스프링 : 프레임워크+ 라이브러리
- 초기 렌더링 필요
- render 함수가 반환하는 결과를 곧바로 DOM에 반영하지 않고, 이전에 render 함수가 만들었던 컴포넌트 정보와 현재 render 함수가 만든 컴포넌트 정보를 비교
- virtual DOM : 갱신이 아닌 다시 만듦, 마지막 렌더링 과정에서 업데이트함
- 리액트는 뷰만 신경 쓰는 라이브러리이므로 기타 기능은 직접 구현하여 사용해야 함
[git Bash]
$cd d: -> D드라이브 접근
$ mkdir KH_React -> 폴더 만들기
$ pwd -> 현재 위치
$ ls -> 폴더목록 보기
yarn create react-app sample_react -> 설치
cd sample-react/ -> 확인
https://tamagotch.tistory.com/85
VScode PowerShell 오류 해결 방법 - 이 시스템에서 스크립트를 실행할 수 없으므로
PowerShell, VScode 스크립트 실행 권한 오류 해결 방법 만약 PowerShell 스크립트 실행 중 아래와 같은 에러 코드를 발견했다면 다음 절차를 따라 쉽게 해결할 수 있을것이다. Error on terminal: nodemon.ps1..
tamagotch.tistory.com
vs 코드에서 터미널에서 yarn start 깔기
js에서 html 문법 사용
import './App.css';
function App() {
let text = "리액트를 시작해 봅시다^^." ;
return (
<div>
<h1>{text}</h1>
</div>
);
}
export default App;
import './App.css';
function App() {
let text = <h1>"리액트를 시작해 봅시다^^."</h1> ;
return (
<div>
{text}
</div>
);
}
export default App;
=> 같은 결과 도출
<JSX>
- Javascript에 XML을 확장한 문법
- html xml차이 : html 닫힘 태그가 없어도 됨(ex. br태그) xml 반드시 닫힘태그가 있어야함
- 완전 js문법이 아님
- 브라우저 실행하기 전에 바벨을 사용하여 jsx를 일반 js형태 코드로 변환 => 해석하기위해 변환필요
import './App.css';
function App() {
const name ="곰돌이사육사";
const element = <h1>안녕하세요. 저는 {name} 입니다.</h1>
return (
<div>
{element}
</div>
);
}
export default App;
=> 데이터 바인딩이 편하다
import './App.css';
function App() {
const name ="곰돌이사육사";
const element = <h1>안녕하세요. 저는 {name} 입니다.</h1>
return (
<div>
<p>안녕하세요.</p>
<p>오늘은 10월 13일 목요일입니다.</p>
</div>
);
}
export default App;
=> p태그만 두개는 불가능(div태그로 감싸야 함)
import './App.css';
function App() {
const name ="곰돌이사육사";
const element = <h1>안녕하세요. 저는 {name} 입니다.</h1>
return (
// 반드시 감싸주는 요소가 필요함
<>
<p>안녕하세요.</p>
<p>오늘은 10월 13일 목요일입니다.</p>
</>
);
}
export default App;
=> 가능 , dom를 전송시 묶음이 필요하기 때문에 빈태그라도 있어야함
import './App.css';
function App() {
const name ="곰돌이사육사";
const validMember = <h1>환영합니다. {name}님.</h1>
const invalidMember = <h1>환영합니다. 방문자님.</h1>
let isMember = false;
if(isMember)return (<>{validMember}</>);
else return(<>{invalidMember}</>)
}
export default App;
function SampleJSX() {
}
// const SampleJSX = () => {
// }
=> 같음
<SampleJSX.js>
function SampleJSX() {
const name ="곰돌이사육사";
const validMember = <h1>환영합니다. {name}님.</h1>
const invalidMember = <h1>환영합니다. 방문자님.</h1>
let isMember = true;
if(isMember)return (<>{validMember}</>);
else return(<>{invalidMember}</>)
}
export default SampleJSX; // 파일 내보내기
<index.js> -> 껍데기만 사용
import React from 'react';
import ReactDOM from 'react-dom/client';
import SampleJSX from './1013Jsx/SampleJSX';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<SampleJSX /> // js 파일 호출
</React.StrictMode>
);
<삼항연산자 이용>
function SampleJSX() {
const name ="라이언";
return(
<div>
{name === "라이언" ? (<h1>라이언 입니다.</h1>):(<h1>라이언이 아닙니다.</h1>)}
</div>
);
}
export default SampleJSX;
<조건문 자체를 렌더링 함>
function SampleJSX() {
const name ="라이언";
// return(
// <div>
// {name === "라이언" ? (<h1>라이언 입니다.</h1>):(<h1>라이언이 아닙니다.</h1>)}
// </div>
// );
return <div>{name === "라이언" && <h1>라이언을 출력합니다.</h1>}</div>
}
export default SampleJSX;
=====> 라이언을 출력합니다.
css : ClassName으로 처리해야함
function SampleJSX() {
const name ="라이언";
const textStyle ={
backgroundColor: "#222",
color:"royalBlue",
fontSize :"2em"
};
return <div style={textStyle}>{name === "라이언" && <h1>라이언을 출력합니다.</h1>}</div>
}
export default SampleJSX;
---> background-color가 아닌 카멜 표기법인 backgroundColor로 사용
import './Sample.css'; // 다른 파일을 연결
function SampleJSX() {
const name ="라이언";
return <div className="textStyle">{name === "라이언" && <h1>라이언을 출력합니다.</h1>}</div>
}
export default SampleJSX;
=> className인 이유 : 예약어 이기 때문에
.textStyle{
background-color: #222;
color : royalblue;
font-size: 2em;
}
<예제>
import "./Sample.css";
const member = {
name: "라이언",
job: "Developer",
addr : "경기도 용인시",
gender : "여성"
}
const getGreeting = (user) => {
if(user) return <h1>환영합니다.{member.name}</h1>
return <h1>환영합니다. 방문자님..</h1>
}
const MemberInfo = () => {
return(
<div>
<p className="title-name">안녕하세요. 저는 {member.name}입니다.</p>
<p className="title-name">직업은 {member.job} 입니다.</p>
<p className="title-name">주소는 {member.addr} 입니다.</p>
<p className="title-name">성별은 {member.gender} 입니다.</p>
<div className="welcome-text">{getGreeting(true)}</div>
</div>
);
}
export default MemberInfo;
.textStyle{
background-color: #222;
color : royalblue;
font-size: 2em;
}
.title-name{
color: royalblue;
font-size: 1.6em;
}
.App {
text-align: center;
}
.welcome-text{
color: orange;
font-size: 1.8em;
font-size: italic;
}
import React from 'react';
import ReactDOM from 'react-dom/client';
import MemberInfo from './1013Jsx/Member';
import SampleJSX from './1013Jsx/SampleJSX';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<input></input>
<MemberInfo />
</React.StrictMode>
);
<게시판 회원용으로 만들어 보기>
import "./Sample.css";
const member = {
nickName : "라이언",
memberNum : "7000",
regDate : "2022/10/13"
}
const getGreeting = (user) => {
if(user) return <h1>환영합니다. {member.nickName}님!</h1>
return <h1>환영합니다. 방문자님!</h1>
}
const MemberInfol = () => {
return(
<div className="memberLine">
<div className="welcome-text">{getGreeting(true)}</div>
<p className="title-name">{member.nickName}</p>
<p className="title-name">회원번호 : {member.memberNum}</p>
<p className="title-name">회원가입일 : {member.regDate}</p>
</div>
);
}
export default MemberInfol;
.memberLine {
border: 1px solid #ccc;
width: 300px;
height: 400px;
text-align: center;
}
.welcome-text{
color : #dba69e;
font-size: 13px;
}
.title-name{
text-align:center;
}
<컴포넌트> : 함수(하나의 기능 단위)
컴포넌트 : 독립적이고 재사용이 가능한 ui를 만들 수 있는 단위
prorps라는 임의의 입력을 받은 후 , 화면에 어떻게 표시되는지를 기술하는 react엘리먼트를 반환
props : 컴포넌트끼리 값을 전달하는 수단, 읽기 전용, 입력값을 바꾸려하지 않고 항상 동일한 입력값에 동일한 결과 반환(순수함수)
"props" : 하나의 덩어리로 넘어감
컴포넌트 : 라이프 사이클 API를 이용하여 컴포넌트가 화면에 나타날 때, 사라질 때, 변화가 일어날 때 주어진 작업 처리, 임의의 메서드를 만들어 특별한 기능을 붙여 줄 수 있음
- 함수형 컴포넌트 -> 가장 많이 사용
<index.js>
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
<welcomeProp.js>
// ()매개변수 넣는 자리
// const WelcomeProp = () =>{
// }
function WelcomeProp(props){
return (
<div>
<h1>안녕하세요. 저는 {props.name}입니다. </h1>
<h1>저의 직업은 {props.jobs}</h1>
</div>
);
}
export default WelcomeProp;
// 매개변수가 덩어리로 되어있어 props.name도 가능
<app.js>
import './App.css';
import WelcomeProp from './1013Jsx/WelcomeProp.js';
function App() {
const element = <WelcomeProp name ="곰돌이사육사" jobs="리액트 개발" />
return(
<div>
{element}
</div>
)
}
export default App;
- 데이터를 가진 하나의 "props"(props는 속성을 나타내는 데이터) 객체 인자를 받은 후 React 엘리먼트를 반환
- -> 유효한 react 컴포넌트
- props는 읽기 전용이며, 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수(항상 일정한 값을 리턴, 내부 영향을 주면 안됨)처럼 동작해야 함
- 컴포넌트의 이름은 항상 대문자로 시작해야함. React는 소문자로 시작하는 컴포넌트를 DOM 태그로 처리 함.
// ()매개변수 넣는 자리
// const WelcomeProp = () =>{
// }
function WelcomeProp(props){
return (
<div>
<h3 style ={{color:props.color}}>안녕하세요. 저는 {props.name}이고, 직업은 {props.job}입니다. </h3>
</div>
);
}
export default WelcomeProp;
// 매개변수가 덩어리로 되어있어 props.name도 가능
import './App.css';
import WelcomeProp from './1013Jsx/WelcomeProp.js';
function App() {
return(
<div>
<WelcomeProp name = "천지훈" job = "변호사" color="blue"/>
<WelcomeProp name = "백마리" job = "변호사" color="orange"/>
<WelcomeProp name = "서민혁" job = "me too" color="green"/>
</div>
)
}
export default App;
<예제>
// ()매개변수 넣는 자리
// const WelcomeProp = () =>{
// }
function WelcomeProp(props){
return (
<div>
<h3 style ={{color:props.color, fontSize:props.font}}>안녕하세요. 저는 {props.name}이고, 직업은 {props.job}입니다. </h3>
</div>
);
}
export default WelcomeProp;
// 매개변수가 덩어리로 되어있어 props.name도 가능
import './App.css';
import WelcomeProp from './1013Jsx/WelcomeProp.js';
function App() {
return(
<div>
<WelcomeProp name = "천지훈" job = "변호사" color="blue" font="1.5em"/>
<WelcomeProp name = "백마리" job = "변호사" color="orange" font="1.3em"/>
<WelcomeProp name = "서민혁" job = "me too" color="green" font="1.4em"/>
</div>
)
}
export default App;
<예제>
function WelcomeProp(props){
return (
<div>
<h3 style ={{color:props.color, fontSize:props.font}}>안녕하세요. 저는 {props.name}이고, 직업은 {props.job}입니다. </h3>
</div>
);
}
//값을 넘겨주지 않았을 경우
WelcomeProp.defaultProps ={
name:"익명",
job:"무직",
color:"black",
font:"2em"
}
export default WelcomeProp;
import './App.css';
import WelcomeProp from './1013Jsx/WelcomeProp.js';
function App() {
return(
<div>
<WelcomeProp name = "천지훈" job = "변호사" color="blue" font="1.5em"/>
<WelcomeProp name = "백마리" job = "변호사" color="orange" font="1.3em"/>
<WelcomeProp name = "서민혁" job = "me too" color="green" font="1.4em"/>
<WelcomeProp />
</div>
)
}
export default App;
<예제>
function WelcomeProp(props){
return (
<div>
<h3 style ={{color:props.color, fontSize:props.font}}>안녕하세요.
저는 {props.name}이고, 직업은 {props.job}입니다. {props.children} </h3>
</div>
// props.children 태그 사이에 값이 넘어옴
);
}
//값을 넘겨주지 않았을 경우
WelcomeProp.defaultProps ={
name:"익명",
job:"무직",
color:"black",
font:"2em"
}
export default WelcomeProp;
import './App.css';
import WelcomeProp from './1013Jsx/WelcomeProp.js';
function App() {
return(
<div>
<WelcomeProp name = "천지훈" job = "변호사" color="blue" font="1.5em">%%%##</WelcomeProp>
<WelcomeProp name = "백마리" job = "변호사" color="orange" font="1.3em">OK</WelcomeProp>
<WelcomeProp name = "서민혁" job = "me too" color="green" font="1.4em"/>
<WelcomeProp />
</div>
)
}
export default App;
[구조분해, 비구조화 할당] : 배열이나 객체의 속성 혹은 값을 해체하여 그 값을 변수에 각각 담아 사용하는 자바스크립트 표현식 => 면접
function WelcomeProp(props){
// 구조분해, 비구조화 할당 : 하나의 덩어리를 각각의 변수로 쪼개냄
const{name, job, font, color, children} = props;
return (
<div>
<h3 style ={{color:color, fontSize:font}}>안녕하세요.
저는 {name}이고, 직업은 {job}입니다. {children} </h3>
</div>
);
}
WelcomeProp.defaultProps ={
name:"익명",
job:"무직",
color:"black",
font:"2em"
}
export default WelcomeProp;
<예제>
const formatDate = (date) => {
return date.toLocaleDateString();
}
const Comment = (props) => {
return(
<div>
<div>
// 서버에서 받은 데이터 이미지 적용 부분
<img src={props.author.avatarUrl} alt={props.author.name}/>
<div>{props.author.name}</div>
</div>
<div>{props.text}</div>
<div>{formatDate(props.date)}</div>
</div>
);
}
export default Comment;
import './App.css';
// import WelcomeProp from './1013Jsx/WelcomeProp.js';
import Comment from './1013Jsx/Comment';
const comment ={
date : new Date(),
text : 'I hope you enjoy learning React!',
author:{
name :"Hello Kitty",
avatarUrl : 'http://placekitten.com/g/64/64'
}
}
function App() {
return(
<div>
<Comment
date ={comment.date}
text ={comment.text}
author={comment.author}
/>
</div>
)
}
export default App;
// 상속하기 위해 임포트
import{ Component } from 'react';
// Component를 상속 받아서 사용
class ClassComp extends Component {
render(){
const name = "곰돌이";
return (
<div>
{name}
</div>
);
}
}
export default ClassComp;
import React from 'react';
import ReactDOM from 'react-dom/client';
import ClassComp from './1013Jsx/ClassComp';
import App from './App';
import './index.css';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<ClassComp />
</React.StrictMode>
);
<state and Lifecycle> => 성능, 타이밍적 이슈가 있음, hooks 기반으로 학습예정
import { Component } from "react";
class Counter extends Component {
constructor(props){
super(props);
// state의 초기값 설정
this.state = {
number: 0
};
}
// 비구조 할당에서 {}필요
render() {
const{number} = this.state;
return(
<div>
<h1>{number}</h1>
// onClick: jsx문법이므로 카멜표기법
<button onClick={() => {this.setState({number: number+1})}}>+1</button>
</div>
)
};
}
export default Counter;
setState : 리액트에서 가지고 있음 -> 화면 갱신 언제? 클릭이 될때는 업데이트 안됨 --> 리액트는 실행부분만 업데이트
import React from 'react';
import ReactDOM from 'react-dom/client';
import ClassComp from './1013Jsx/ClassComp';
import App from './App';
import './index.css';
import Counter from './1013Jsx/Counter';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* <ClassComp /> */}
<Counter />
</React.StrictMode>
);
<리액트 핵심 문법>
--> 대표적인 특징
[useState 사용하기]
state 컴포넌트 내부에서 바뀔 수 있는 값을 의미
props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값
import {useState} from 'react';
// message
// setMessage : 내부 메세지의 값을 변경하기 위한 값 (=자바의 setter 유사)
// useState : 상태의 변경 정보를 가지고 있음
// useState가 바뀔 때 리벤더링(바뀐값만 그림)을 함(DOM을 부시고 새로 만듦)
//
const Say = () => {
// 배열 만들기
const [message, setMessage] = useState('');
// 버튼을 두개 쓴 이유 ? 하나는 값을 바꿈, 값을 씀(부시고 다시 씀) ==> **화면 갱신을 위함**
// 값을 날리고 쓰고 있음
const onClickEnter = () => setMessage("안녕하세요!!!");
// 버튼을 누르면 message값으로 값이 바뀜(바꾸면서 화면을 업데이트 함)
const onClickLeave = () => setMessage("안녕히가세요!!!");
const [color, setColor] = useState('black');
// 화면 갱신이 어려움 => 이것을 개선하기 위해 위 코드 처럼 버튼을 두개 만듦
let prnMsg = "없음";
const testClick = () => {
prnMsg = "어서오세요^^";
console.log(prnMsg);
}
// 콘솔에 찍히지만 화면에는 업데이트가 되지 않음 (리벤더링이 되고 있지 않기 때문에)
return(
<div>
{/* 메세지를 업데이트하면서 리밴더링함 */}
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<button onClick={testClick}>테스트메세지</button>
//<h1 style={{color}}>{message}</h1>
<h1 style={{color}}>{prnMsg}</h1>
<button style ={{color : 'red'}} onClick={() => (setColor('red'))}>빨간색</button>
<button style ={{color : 'green'}} onClick={() =>(setColor('green'))}>초록색</button>
<button style ={{color : 'blue'}} onClick={() => (setColor('blue'))}>파란색</button>
</div>
)
}
export default Say;
import React from 'react';
import ReactDOM from 'react-dom/client';
import ClassComp from './1013Jsx/ClassComp';
import App from './App';
import './index.css';
import Counter from './1013Jsx/Counter';
import Say from './1013Jsx/Say';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* <ClassComp /> */}
{/* <Counter /> */}
<Say />
</React.StrictMode>
);
=> **prnMsg를 사용하면 화면 업데이트가 안됨 그러나 콘솔은 업데이트 됨
--> 반복문 조건문 사용하면 안됨
import {useState} from 'react';
const Clock = () => {
const [date, setDate] = useState(new Date());
const tick = () => {
setDate(new Date());
}
setInterval(tick, 1000);
// 1초에 한번씩 바꿔줌 (렌더링함)
return(
<div>
<h1>현재 시간을 표시 합니다.</h1>
<h2>현재 시간은 {date.toLocaleTimeString()}</h2>
</div>
)
}
export default Clock;
<리액트 정리>
- 컴포넌트 : 데이터(props)를 입력 받아 view(state)상태에 따라 DOM Node를 출력하는 함수
- 함수형 컴포넌트 : function Component(props) { return <div>Hello, {props.name}</div>;}
- 클래스형 컴포넌트 :class Component extends React Component{
- constructor(props){
- super(props);}
- render () { // 상속받은 화면 출력 함수, 클래스형 컴포넌트는 render() 필수
- return <div>Hello, {this.props.name{</div>;}
- state : 동적인 데이터를 다룰때
'국비학원 교육 일지' 카테고리의 다른 글
[58일차] 국비교육 (0) | 2022.10.14 |
---|---|
[56일차] 국비 교육 (0) | 2022.10.12 |
[55일차] 국비 교육 (0) | 2022.10.07 |
[54일차] 국비 교육 (1) | 2022.10.06 |
[53일차] 국비교육 (1) | 2022.10.05 |