#리엑트 실행 명령어
cd blog
npm start
Q. React 는 프레임워크일까? 라이브러리일까?
A. 라이브러리
1) 프레임워크 : 원하는 기능 구현에 집중하여 개발할 수 있도록 필요한 기능을 갖추고 있는 것, 일정한 형태를 가지고 다양한 형태의 결과물을 만드는 것
2) 라이브러리 : 소프트웨어를 개발할 때 프로그래밍 사용하는 비휘발성 자원의 모임, 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것
둘의 차이점은 어플리케이션의 제어 흐름의 권한을 누가 가지고 있느냐가 핵심
https://canoe726.tistory.com/23
좋아요 예제
/* eslint-disable */
import './App.css';
import { useState, useEffect } from 'react';
//class UserApp extends React.Component{ }
function App() {
let [title] = useState(['혜화 맛집 튀김' , '송파 샤브샤브','홍대 일식집'])
//값이 하나씩 대응된다.
let [like, setLike] = useState(0);
//useState("string") 훅은 배열 형태로 2개의 값이 전달된다.
function fnlike(){
setLike(like+1);
}
return (
<div className="App">
{title[0]} <span onClick={ fnlike }>좋아요</span> {like}
</div>
);
}
export default App;
타이틀 정렬 예제
수업때 대강 넘어감, 찾아서 공부하자
교재 92~117p
p90
function()은 return()안의 name을 가리킴 (검둥이)
() => 는 class의 name을 가리킴 (흰둥이)
//App.js
import React from 'react';
import './App.css';
import MyComponent from './MyComponent';
function App() {
return (
<MyComponents/>
);
}
export default App;
//MyComponents.js
const MyComponent = () => {
return <div>나의 새롭고 멋진 컴포넌트</div>
};
export default MyComponent; // 이 파일을 import할 때, MyComponent클래스를 불러오도록 설정한다
결과 : 나의 새롭고 멋진 컴포넌트
//App.js
import React from 'react';
import './App.css';
import MyComponent from './MyComponent';
function App() {
return (
<MyComponents name="React"/>
);
}
export default App;```
```js
//MyComponents.js
const MyComponent = (props) => {
return <div>안녕하세요, 제 이름은 {props.name}입니다.</div>
};
export default MyComponent;
결과 : 안녕하세요, 제 이름은 React입니다.
!!! 기본값 지정하는 방법은 MyComponents.js에 아래 코드 추가
MyComponent.defaultProps = {
name : '기본 이름'
}
//App.js
import React from 'react';
import './App.css';
import MyComponent from './MyComponent';
function App() {
return (
<MyComponents name="React">리엑트</MyComponent>
);
}
export default App;
//MyComponents.js
const MyComponent = (props) => {
return (
<div>
안녕하세요, 제 이름은 {props.name}입니다.
children 값은 {props.children}입니다.
</div>
)
};
export default MyComponent;
결과 : 안녕하세요, 제 이름은 React입니다. children 값은 리엑트입니다
1번방법
//MyComponents.js
const MyComponent = (props) => {
const { name, children } = props;
return (
<div>
안녕하세요, 제 이름은 {name}입니다.
children 값은 {children}입니다.
</div>
)
};
export default MyComponent;
2번방법
//MyComponents.js
const MyComponent = ({ name, children }) => {
return (
<div>
안녕하세요, 제 이름은 {name}입니다.
children 값은 {children}입니다.
</div>
)
};
export default MyComponent;
먼저 상단에 import시켜줘야 한다.
import PropTypes from 'prop-types';
이후 MyComponents.js파일에 아래 코드 추가
MyComponent.propTypes = {
name : PropTypes.string
}
결과: name값은 무조건 문자열 형태로 전달됨.
prpTypes를 지정하지 않았을 때 경고 메시지를 띄워주는 작업.
//MyComponents.js
const MyComponent = ({ favoriteNumber }) => {
return (
<div>
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
)
};
MyComponent.propTypes = {
favofiteNumber: PropTypes.number.isRequired
}
export default MyComponent;
결과 : App.js에서 favoriteNumber가 숫자가 제대로 넘어오지 않았기 때문에 경고가 뜬다. App.js에 favoriteNumber={1} 을 추가해주자
위의 컴포넌트는 다음과 같이 변환할 수 있다. 차이를 주목해보자
//MyComponent.js
import { Component } from "react";
import PropTypes from 'prop-types';
class MyComponent extends Component{
static defaultProps = {
name : '기본 이름'
};
static propTypes = {
name : PropTypes.string,
favoriteNumber : PropTypes.number.isRequired
};
render(){
const {name, favoriteNumber, children} = this.props;
return(
<div>
안녕하세요, 제 이름은 {name}입니다.
child값은 {children}입니다.
</div>
);
}
}
export default MyComponent;
import{Component}from 'react';가 추가되었다.
default와 propType가 MyComponent안으로 들어왔다.
state는 컴포넌트 내부에서 바뀔 수 있는 값
props는 부모로부터 전달받은 값으로 컴포넌트 내부에서 변경불가능
여기서 state는 두가지 종류가 있는데 하나는 클래스형 컴포넌트의 state, 다른 하나는 useState
//state 예제
import {Component} from 'react';
class Counter extends Component{
constructor(props){
super(props)
// state의 초기값 설정하기
this.state = {
number:0
};
}
render(){
const {number} = this.state; // state를 조회할때는 this.state로 조회
return(
<div>
<h1>{number}</h1>
<button
// onclick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
onClick={()=>{
// this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
this.setState({number:number+1});
}},
()=>{
console.log('setState호출');
console.log(this.state);
}
>+1</button>
</div>
);
}
}
export default Counter;
결과
//기존
constructor(props){
super(props)
// state의 초기값 설정하기
this.state = {
number:0
};
}
//New
state = {
number: 0,
fixedNumber: 0
}
//Say.js
import { useState } from 'react';
const Say = () => {
const[message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕하세요');
const onClickLeave = () => setMessage('안녕히 가세요!');
return(
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1>{message}</h1>
</div>
);
};
export default Say;
결과 :
!!! 여러개의 컴포넌트를 다룬다면? (성공x)
//App.js
import MyComponent1 from './components/MyComponent1';
import MyComponent2 from './components/MyComponent2';
<MyComponente1/><MyComponente2/>
//component.js
export default {MyComponent1 , MyComponent2 ...};
컴포넌트를 활용한 프론트엔드
전
• HTML 로 문서 구조 구현하고,
• CSS 로 스타일을 입히고,
• JavaScript 로 DOM 을 조작한다. (기능, 동작)
후
• 컴포넌트를 정의하고
• 실제 DOM에 컴포넌트를 그려준다.
ReactDom.render(리엑트컴포넌트, document.querySelector('#root'));
React.createElement(
type, //태그이름 문자열, 리엑트 컴포넌트, React.Fragment
[props], //리엑트 컴포넌트에 넣어주는 데이터 객체
[...children] //자식으로 넣어주는 요소들
)
//1.태그이름문자열 type
ReactDom.render(
React.createElement('h1',null,`type is "tagNameString" !!!.`),document.querySelector('#root')
);
//2. React Component type
const Component type
Const Component = props => {
return React.createElement(
'p',
null,
`type is "tagNameString" !!!.`
);
};
ReactDom.render(
React.createElement(Component,null,null),document.querySelector('#root')
);
교재 p194
컴포넌트가 렌더링 될 때마다 특정 작업을 수행하게 설정 할 수 있는 훅.
컴포넌트 안에 useEffect(()=>{});를 사용해서 구현하면 된다.
ex) console.log('렌더링이 완료되었습니다!');
// !!!처음 렌더링될때만 실행시키고 싶다면?
useEffect(()=>{console.log('렌더링이 완료되었습니다!');},[]);
// !!!특정 값이 업데이트 될 때만 실행하고싶다면?
useEffect(()=>{console.log(name);},[name]);
가시성관리
//App.js
import { useState } from "react";
import Info from './Info';
const App = () => {
const [visible, setVisible] = useState(false);
return (
<div>
<button onClick={() => {
setVisible(!visible);
}}
>
{visible ? '숨기기' : '보이기'}
</button>
<hr />
{visible && <Info />}
</div>
);
};
export default App;
지금은 어려우니 17장 학습 후 추후 학습
값이 변경될 때마다(onChange)계산될 필요가 없고, 입력이 되었을 때만 연산 되게 함으로써 낭비를 줄이게 하는 훅.
//Average.js
import { useState,useMemo } from "react";
{/* useMemo를 사용하겠다. */}
const getAverage = numbers => {
console.log('평균값 계싼 중..');
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a,b) => a+b);
return sum / numbers.length;
}
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const onChange = e => {
setNumber(e.target.value);
};
const onInsert = e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
}
const avg = useMemo(()=>getAverage(list),[list]);
{/*기존의 getAverage(list)대신 추가된 함수 */}
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value,index)=>(
<li key={index}>{value}</li>
))}
</ul>
<div>
<b>평균값 : </b> {avg}
{/* //기존의 코드 : getAverage(list) -> avg */}
</div>
</div>
);
};
export default Average
결과 : 값이 바뀌어도 더이상 계산이 돌아가지 않음.
useCallback은 useMemo와 상당히 비슷한 함수.
값이 아닌 만들어 놨던 함수를 재사용한다.
위의 Average함수에서 onChange와 onInsert는 렌더링 될때마다 새로 함수가 생성되고 있는데 이 부분을 최적화 할 수 있다.
//변경,추가되는 부분
import { useState,useMemo,useCallback } from "react";
...
const onChange = useCallback(e => {setNumber(e.target.value);},[]);
//컴포넌트가 처음 렌더링 될 때만 함수 생성
const onInsert = useCallback( e => {const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
},[number,list]);
//number 혹은 list가 바뀌었을 때만 함수 생성
...
ref를 쉽게 사용해주는 훅, 사용법만 간단히 보고 가자
//변경,추가되는 부분
import { useState,useMemo,useCallback,useRef } from "react";
...
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState('');
const inputEl = useRef(null);
...
const onInsert = useCallback( e => {const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
},[number,list]);
inputEl.current.focus();
//number 혹은 list가 바뀌었을 때만 함수 생성
...
return(
<div>
<input value={number} onChange={onChange} ref={inputEl} />
결과 : useRef를 통해 만든 객체 안의 current값이 실제 엘리먼트를 가리킨다.
프로그래머스 lv0
추가학습필요 :
여러개의 컴포넌트 동시에 app에 넣는방법,
타이틀 정렬 예제