<body>
<div id="root"></div>
</body>
ReactDOM.render(<App/>,document.getElementById("root"))
리액트 컴포넌트 안에서 id 사용 가능 -> 권장 X
원칙적 : unique한 DOM의 id
문제 상황 발생 : 중복 id 가진 DOM 생성됨
ref 의 경우 : 전역적 작동 X, 컴포넌트 내부에서만 작동 X -> 문제 발생 ㅌ
불가피한 if 사용 필요한 경우 : 추가적 txt 붙여야 함
순수 js
: DOM을 꼭 직접적으로 건들어야 하는 경우 사용
웹에서 input을 검증하기 위해 특정 id가진 input에 클래스 설정
<head>
(...)
<script>
function validate(){
var input=document.getElementById("password");
input.className="";
if(input.value==="0000"){
input.className="success";
}
else{
input.className="failure";
}
}
</script>
(...)
</head>
<body>
<input type="password" id="password"/>
<button onClick="validation()">Validation</button>
</body>
react
: DOM에 접근하지 않고 리액트 컴포넌트의 state 이용
//input 검증 결과에 따른 화면 스타일
.success {
/*입력한 값이 검증된 경우 (비번과 동일함)*/
background-color: lightgreen;
}
.failure {
/*입력한 값이 검증되지 않은 경우 (비번과 동일하지 않은 경우)*/
background-color: lightcoral;
}
/
import React,{Component} from 'react';
import "./ValidationSample.css";
//1. Validation 컴포넌트 생성
class ValidationSample extends Component{
//1-1. 초기 state 설정
state={
password:"", //비밀번호
clicked:false, //버튼 클릭 X
validated:false //비밀번호 검증 X
}
//2. 이벤트(input 입력) 발생시 실행되는 함수
handleChange=(e)=>{
this.setState(
//2-1. 입력 event의 값을 password의 값으로 설정
{
password:e.target.value
}
)
}
//3. 버튼 클릭시 실행되는 함수
handleButtonClick=()=>{
this.setState(
{
clicked:true,
//3-1. 버튼 클릭 여부 true로 설정
validated:this.state.password==="0000"
//3-2. 입력한 비밀번호의 값이 0000인 경우 검증 상태 true됨
}
)
}
render(){
return(
<div>
<input
type="password"
//4-1. input에 입력되는 값은 password임
value={this.state.password}
//4-2. input의 값은 state의 password 값임
onChange={this.handleChange}
//4-3. input에 값이 입력되는 event 발생 시 실행 되는 함수
className={this.state.clicked?(this.state.validated?"success":"failure"):""}
//4-4. 입력된 값 검증 결과 : 참 & 유저가 click해 제출 -> success
//4-4. 입력된 값 검증 결과 : 거짓 & 유저가 click해 제출 -> failure
//4-4. 입력된 값 검증 결과 : 거짓 & 유저가 아직 click해 제출 안함 -> ""로 이전 상태 그대로임
/>
<button onClick={this.handleButtonClick}>검증하기</button>
</div>
);
}
}
export default ValidationSample;
import './App.css';
import React,{Component} from 'react';
import ValidationSample from './ValidationSample';
class App extends Component{
render(){
{
return (
<ValidationSample/>
);
}
}
}
export default App;
State로 해결 불가능해 ref 사용해 DOM에 직접적인 접근하는 경우
1. 특정 input에 포커스 주기
2. 스크롤 박스 조작
3. Canvas 요소에 그림 그리기
ref 속성 추가 : props 설정과 유사
콜백 함수의 파라미터 : ref
콜백 함수 배누에서 컴포넌트 멤버 변수에 ref 담는 코드
<input ref={(ref)=>{this.input=ref}} (....)/>
this.input=input 요소의 DOM
<input
ref={(ref)=>this.input=ref}
//this.input은 input 요소의 DOM을 가르킴
type="password"
value={this.state.password}
onChange={this.handleChange}
className={this.state.clicked?(this.state.validated?"success":"failure"):""}
/>
handleButtonClick=()=>{
this.setState(
{
clicked:true,
validated:this.state.password==="0000"
}
);
this.input.focus();
/*버튼 눌렀을 때 focus가 버튼으로 넘어가
input 텍스트 요소에 커서 보이지 X 인 걸 막음
-> 버튼 눌렀을 때 focus가 다시 input 쪽으로 자동으로 넘어감*/
}
컴포넌트 내부에 있는 DOM을 컴포넌트 외부에 사용시 사용
<MyComponent ref={(ref)=>{this.myComponent=ref}}/>
스크롤 박스 있는 컴포넌트 생성, 부모 컴포넌트에서 스크롤 다운 작업 실행
import React,{Component} from 'react';
//1. ScrollBox 컴포넌트 생성
class ScrollBox extends Component{
//2. JSX 인라인 스타일링 문법으로 스크롤 박스 생성
render(){
const style={
border: "1px solid black",
height: "300px",
width :"300px",
overflow:"auto",
position:"relative"
};
const innerstyle={
width : "100%",
height : "650px",
background:"linear-gradient(white, black)"
}
return (
//3.최상위 DOM에 ref 달기
<div style={style}
ref={(ref)=>{this.box=ref}}>
<div style={innerstyle}/>
</div>
)
}
}
export default ScrollBox;
import './App.css';
import React,{Component} from 'react';
import ValidationSample from './ValidationSample';
import ScrollBox from './ScrollBox';
class App extends Component{
render(){
{
return (
<ScrollBox/>
);
}
}
}
export default App;
DOM 노드가 가진 다음의 활용해 컴포넌트에 스크롤바를 맨 아래로 내리는 매서드 생성
- scrollTop : 세로 스크롤바 위치 (0~350)
- scrollHeight : 스크롤 박스 내부 높이 (650)
- clientHeight : 스크롤 박스 외부 높이 (300)
=> 스크롤바 맨 아래 = scrollHeight - clientHeight
import React,{Component} from 'react';
class ScrollBox extends Component{
//스크롤바 가장 밑으로 내리는 메서드 작성
scrollToBottom=()=>{
const {scrollHeight, clientHeight}=this.box;
//비구조화 할당 문법
this.box.scrollTop=scrollHeight-clientHeight;
}
render(){
const style={
border: "1px solid black",
height: "300px",
width :"300px",
overflow:"auto",
position:"relative"
};
const innerstyle={
width : "100%",
height : "650px",
background:"linear-gradient(white, black)"
}
return (
<div style={style}
ref={(ref)=>{this.box=ref}}>
<div style={innerstyle}/>
</div>
)
}
}
export default ScrollBox;
import './App.css';
import React,{Component} from 'react';
import ValidationSample from './ValidationSample';
import ScrollBox from './ScrollBox';
class App extends Component{
render(){
{
return (
<div>
<ScrollBox ref={(ref)=>this.scrollBox=ref}/>
<button onClick={()=>this.scrollBox.scrollToBottom()}> 맨밑으로</button>
</div>
);
}
}
}
export default App;
onClick={this.scrollBox.scrollBottom}
으로 작성하는 경우 컴포넌트 첫 렌더링 때 this.scrollBox
가 undefined임.onClick
에서 화살표 함수 문법 이용해 새로운 함수 만들고 그 함수 내부에서 scrollBox.scrollToBottm
실행 시 오류 없음객체에서 특정 값 추출해 따로 레퍼런스 만들 때 유용
//예제1.
const obj={
foo:1,
bar:2
};
const {foo,bar}=obj;
console.log(foo,bar);
//예제2.
const obj={
foo:1,
bar:2
}
function print({a,b}){
console.log(a,b);
}
print(obj);
리액트 컴포넌트에서 state나 props 참조시 자주 사용
render(){
const {name,num}=this.props;
return(
<div>
<div>{name}</div>
<div>{num}</div>
</div>
)
}