- Reactive programming (반응형 프로그래밍)
- MVC의 V를 React가 관리
- 가상돔 : 필요한 부분만 렌더링
npx create-react-app 폴더이름
을 통해 입력한다.
에러가 난다면 이를 참고
- 도메인
- 역할
- 크기
import logo from './logo.svg';
import PropTypes from 'prop-types'
function Logo(props){
return (
<img src={logo} alt="logo" className="App-logo"
style={{width:props.size , height:props.size}}/>
)
}
Logo.defaultProps = {
size : 200
}
Logo.propTypes = {
size : PropTypes.number
}
export default Logo;
import Logo from './components/Logo'
...
function App() {
return (
<div className="App">
<header className="App-header">
<Logo size="100px"/>
<Logo />
...
export 한 Logo 컴포넌트를 import하여 태그로 사용한다.
<Logo size="100px"/>
)""
를 붙여야하고 숫자라면 {}
를 붙여야 한다. function Logo(props){
return (
<img src={logo} alt="logo" className="App-logo"
style={{width:props.size , height:props.size}}/>
)
}
Logo.defaultProps = {
size : 200
}
해당 매개변수 값이 주어지지 않을 때 사용하는 defaultProps는 다른 방법으로도 가능하다.
function Logo({size = 200}){
return (
<img src={logo} alt="logo" className="App-logo"
style={{width:size , height:size}}/>
)
}
- components/Counter/index.js
- App.js
import {useState} from "react";
function Counter({onIncrease, onDecrease}){
const [count , setCount] = useState(0);
const handleIncrease = () => {
setCount(count+1)
if(onIncrease) onIncrease(count + 1)
}
const handleDecrease = () => {
setCount(count-1)
if(onDecrease) onDecrease(count - 1)
}
return (
<div>
<span style={{fontSize:40}}>{count}</span><br/>
<button onClick={handleIncrease}>+</button>
<button onClick={handleDecrease}>-</button>
</div>
)
}
export default Counter;
if문을 넣은 이유는 좀 더 안전하게 만들기 위해서이다.
만약 App.js에서 Counter에 onIncrease나 onDecrease가 선언되어있지않으면 에러가 난다.
import Counter from './components/Counter'
import {useState} from "react"
function App(){
const [totalCount , setTotalCount] = useState(0)
return (
<div>
TotalCount : {totalCount}
<Counter
onIncrease={()=>{setTotalCount(totalCount + 1)}}
onDecrease={()=>{setTotalCount(totalCount - 1)}}>
</Counter>
<Counter
onIncrease={()=>{setTotalCount(totalCount + 1)}}
onDecrease={()=>{setTotalCount(totalCount - 1)}}>
</Counter>
<Counter
onIncrease={()=>{setTotalCount(totalCount + 1)}}
onDecrease={()=>{setTotalCount(totalCount - 1)}}>
</Counter>
</div>
)
}
export default App;
컴포넌트에서 상태를 관리용 함수
useState 를 사용 할 때에는 상태의 기본값을 파라미터로 넣어서 호출해줍니다. 이 함수를 호출해주면 배열이 반환되는데요
여기서 첫번째 원소는 현재 상태, 두번째 원소는 Setter 함수
const numberState = useState(0);
const number = numberState[0];
const setNumber = numberState[1];
const [ number , setNumber ]= useState(0);
- 각각의 버튼 카운트 + -
- 각각에 영향을 받은 전체 카운트 + -
지역 상태관리를 위해 useState 사용
handleIncrease , handleDecrease 버튼 이벤트에 등록하여 처리
props , Event Bus , Redux 등을 이용할 수 있으나
props를 사용
부모 컴포넌트 App.js에서 props를 통해
onIncrease
와onDecrease
를 받고 App.js에서 각각이 실행할 때 setTotalCount를 이용해 totalCount 변화를 처리
컴포넌트가 마운트 됐을 때 (처음 나타났을 때), 언마운트 됐을 때 (사라질 때), 그리고 업데이트 될 때 (특정 props가 바뀔 때) 특정 작업을 처리하는 방법
두번째 파라미터가 빈배열이라면 처음 로드될 때 실행(ex 초기 이벤트 / API호출)
첫번째 파라미터에 이벤트가 등록되어있다면 return을 통해 핸들러 삭제가 필요하다 ( return 부분은 컴포넌트가 제거될 때 실행 )
import React, { useEffect } from 'react';
...
useEffect(() => {
console.log('컴포넌트가 화면에 나타남');
return () => {
console.log('컴포넌트가 화면에서 사라짐');
};
}, []);
ex)
useEffect(()=>{
console.log('totalCount 변경!')
},[totalCount])
totalCount만 변경될 때 콘솔이 출력되는 것이 아니라
마운트 될 때도 실행된다.
ex)
const mounted = useRef(false)
useEffect(()=>{
if(!mounted.current){
mounted.current = true;
}
else {
console.log('totalCount 변경!')
}
},[totalCount])
이렇게 쓰면 콘솔이 처음에 mount 될때 실행되지 않는다.
- Dom 직접 접근
- 지역변수로 사용
useRef : 값이 변경되도 다시 렌더링 X
useState : 값이 변경되면 다시 렌더링 O