- onClick
- hook
- 예제
- className 변경
- 컴포넌트 분리
- onChange
- ref
1) onClick
import React from 'react';
const Test1 = () => {
const handleClick1 = () => {
alert('HELLO')
}
const handleClick2 = () => {
alert('WORLD')
}
const handleClick3 = () => {
alert('안녕 세상')
}
const make = (num) => {
alert(num)
}
const make1 = (x, y) => {
alert(`${x}, ${y}`)
}
return (
<div style={{margin:'30px'}}>
<p>
<button onClick={handleClick1}>BTN1</button>
<button onClick={handleClick2}>BTN2</button>
<button onClick={handleClick3}>BTN3</button>
</p>
<p>
<button
onClick={() => { console.log(4) }}
>BTN4</button>
<button onClick={() => console.log(5)}>BTN5</button>
<button onClick={() => {
console.log(6)
console.log(6)
console.log(6)
}}>BTN6</button>
</p>
<p>
<button onClick={() => make(100)}>BTN7</button>
<button onClick={() => make1(10, 30)}>BTN8</button>
<button>BTN9</button>
</p>
</div>
);
};
export default Test1;
onClick은 js에서 addEventListener('click')과 같은 기능을 한다.
click 이벤트 발생 시 실행되는 함수를 넣을 수 있는데, BTN1-3처럼 위에서 선언한 함수를 넣거나 실행문이 간단할 경우 함수 선언 없이(BTN4) 직접 넣을 수 있다.
또한 매개변수가 들어가는 함수의 경우 onClick={make(100)}처럼 작성할 경우 페이지가 열리자마자 실행되므로 ()=>make(100) 처럼 호출을 해야 한다.
2) hook
import React from 'react';
const Test2 = () => {
let num = 0
const increment = () => {
num = num + 1
console.log(num);
}
return (
<div style={{margin:'30px'}}>
<h2>count : {num}</h2>
<button onClick={increment}>증가</button>
</div>
);
};
export default Test2;
위와 같이 코드를 작성하고 증가 button을 누르면 consol 창에선 증가된 num이 확인 가능하지만 출력이 되지 않는다.
return으로 받은 것을 화면에 출력하는 것을 랜더링이라고 하는데 React는 랜더링 시 기존 값을 기억하지 못하고 새로 만들기 때문이다.
따라서 값을 유지시키고 업데이트 가능한 hook를 사용해야 한다.
import React, { useState } from 'react';
const Test4 = () => {
const [count, setCount] = useState(0)
const incre = () => {
setCount(count+1)
}
const decre = () => {
setCount(count-1)
}
const reset = () => {
setCount(0)
}
return (
<div>
<h1>숫자 : {count}</h1>
<p>
<button onClick={incre}>증가</button>
<button onClick={decre}>감소</button>
<button onClick={reset}>초기화</button>
</p>
</div>
);
};
export default Test4;
const [ 변수, 함수 ] = useState('초기값')을 추가해 주고 이벤트 함수에서 변숫값을 변경해 주는 함수를 호출해 값을 바꾸어 주면 된다.
3) 예제
import React, { useState } from 'react';
const Test6 = () => {
const [isShow, setIsShow] = useState(false)
const onShow = () => {
setIsShow(true)
}
const onHide = () => {
setIsShow(false)
}
const onToggle = () => {
setIsShow(isShow ? false : true)
}
const css1 = { width: 100, height: 100, background: 'tomato', border: '1px solid black',
}
return (
<div style={{ margin: '30px' }}>
<p>
<button onClick={onShow}>SHOW</button>
<button onClick={onHide}>HIDE</button>
<button onClick={onToggle}>SHOW & HIDE</button>
</p>
{
isShow ? <div style={css1}></div> : null
}
{
isShow && <div style={css1}></div>
}
</div>
);
};
export default Test6;
isShow라는 변수를 이용해 div를 나타내고 숨기는 버튼을 구현해 보았다.
기본값은 false이고 onShow 버튼을 누르면 isShow가 true, onHide를 누르면 false로 바뀌게 된다.
이 불린 값을 받아 return문 안에서 삼항연산자를 이용해 div를 출력하거나 null을 출력하게 된다.
또한 && 연산자를 사용해서 isShow가 true일 때만 div를 출력하도록 해보았다.
4) className 변경
import React, { useState } from 'react';
import './Test7.scss'
const Test7 = () => {
const [isClass, setIsClass] = useState(false)
const onAdd = () => {
setIsClass(true)
}
const onRemove = () => {
setIsClass(false)
}
const onToggle = () => {
setIsClass(!isClass)
}
return (
<div className="wrap">
<p className="on"> HELLO WORLD </p>
<p className="on1"> HELLO WORLD </p>
<p className="test on"> HELLO WORLD </p>
<hr />
<p className={isClass ? 'on' : ''}> HELLO WORLD </p>
<p className={isClass ? 'on1' : ''}> HELLO WORLD </p>
<p className={`test ${isClass ? 'on' : ''}`}> HELLO WORLD </p>
<div>
<button onClick={onAdd}>classList.add</button>
<button onClick={onRemove}>classList.remove</button>
<button onClick={onToggle}>classList.toggle</button>
</div>
</div>
);
};
export default Test7;
위 예제와 비슷하게 isClass 변수를 사용해 true, false 값을 받아 class를 추가해 주고 제거해 주는 기능을 하는 버튼을 만들어 보았다.
5) 컴포넌트 분리
Test8Data.js
export default [
{ id: 1, name: '진기주', age: 20, addr: '서울', done: true },
{ id: 2, name: '김동욱', age: 22, addr: '제주', done: true },
{ id: 3, name: '서지혜', age: 25, addr: '경기', done: false },
{ id: 4, name: '이원정', age: 21, addr: '부산', done: true },
{ id: 5, name: '지혜원', age: 26, addr: '울산', done: false },
{ id: 6, name: '김예지', age: 25, addr: '전주', done: false }
]
Test8Sub.js
import React from 'react';
const Test8Sub = ({ item }) => {
const {id, name, age, addr, done} = item
return (
<tr>
<td>{id}</td>
<td>{name}</td>
<td>{age}세</td>
<td>{addr}</td>
<td>{done?'동의':'비동의'}</td>
</tr>
);
};
export default Test8Sub;
Test8.js
import React from 'react';
import './Test8.scss';
import '../assets/css/reset.css'
import Test8Sub from './Test8Sub';
import dataList from "../assets/api/Test8Data";
const Test8 = () => {
return (
<div>
<table className='list'>
<caption>회원명단</caption>
<colgroup>
<col className="num" />
<col className="name" />
<col className="age" />
<col className="addr" />
<col className="consent" />
</colgroup>
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>나이</th>
<th>주소</th>
<th>동의여부</th>
</tr>
</thead>
<tbody>
{
dataList.map(item => <Test8Sub key={item.id} item={item} />)
}
</tbody>
</table>
</div>
);
};
export default Test8;
data 수정 및 추가 등 관리가 편하도록 컴포넌트를 여러 개로 나누었다.
우선 Test8에서 객체가 들어있는 Test8Data를 import 받아 dataList로 만들고, map을 사용하여 dataList 수만큼 Test8Sub가 실행되도록 했다.
tr이 생성될 때마다 key값을 넣어주고 비구조 할당을 통해 간단하게 각각 맞는 데이터를 td에 넣어주었다.
6) onChange
import React, { useState } from 'react';
const Test9 = () => {
const [userid, setUserid] = useState('')
const [userpw, setUserpw] = useState('')
const changeInput1 = (e) => {
setUserid(e.target.value)
}
const changeInput2 = (e) => {
const { value } = e.target
setUserpw(value)
}
const onReset = () => {
setUserid('')
setUserpw('')
}
return (
<div style={{ margin: '30px' }}>
<input type="text" onChange={changeInput1} value={userid}/>
<input type="text" onChange={changeInput2} value={userpw}/>
<button onClick={onReset}>초기화</button>
<hr />
<h3>ID : {userid}</h3>
<h3>PW : {userpw}</h3>
</div>
);
};
export default Test9;
js에서도 input의 value값을 가져와 사용하는 예제를 만들어 보았는데 React를 활용해 구현해 보았다.
7) ref
import React, { useRef, useState } from 'react';
const Test11 = () => {
const [userid, setUserid] = useState('')
const [userpw, setUserpw] = useState('')
const idRef = useRef()
const changeInput1 = (e) => {
setUserid(e.target.value)
}
const changeInput2 = (e) => {
const { value } = e.target
setUserpw(value)
}
const onReset = () => {
setUserid('')
setUserpw('')
idRef.current.focus()
}
return (
<div style={{ margin: '30px' }}>
<input type="text" onChange={changeInput1} value={userid} ref={idRef}/>
<input type="text" onChange={changeInput2} value={userpw}/>
<button onClick={onReset}>초기화</button>
<hr />
<h3>ID : {userid}</h3>
<h3>PW : {userpw}</h3>
</div>
);
};
export default Test11;
ref는 DOM node나 React element에 접근할 때 사용한다.
js의 document.querySelector 처럼 요소를 선택할 수 있다.
위의 예제를 ref를 사용해서 구현해 보았는데 남용해서 사용하면 좋지 않다고 한다.
const 사용자정의 = useRef(null);
const 사용자정의 = useRef(); 기본값 null은 생략할 수 있다.
<태그 ref={사용자정의}>
사용자정의.current