입력값을 받는 element들에게 value값으로 state
를 걸어주고 setState()
메서드를 사용하여 상태를 변경하는 이벤트 핸들러를 만들어 이벤트를 걸어준다.
class FormControl extends React.Component {
state = {
value: '',
}
handleChange = (e) => {
this.setState({ value: e.target.value })
}
render() {
return (
<input
value={this.state.value}
onChange={this.handleChange}
/>
)
}
}
React 컴포넌트는 폼을 통해 입력된 사용자의 값을 제어 할 수 있다.
React를 통해 값이 관리되는 입력 요소는 컨트롤 컴포넌트(Controlled Component)이다.
Controlled Component
를 사용하면 모든 state
의 업데이트는 연결 된 이벤트 리스너에 의해 처리 된다.
Controlled Component
를 통해 사용자의 입력 내용을 업데이트 하거나, 유효성검사 수행이 가능하다.
하나 이상의 <input />
을 하나의 리스너로 컨트롤 할 수 있다.
여러 개의 컨트롤을 제어하기 위해서는 name 속성
을 설정해야 한다.
class MultiControlInputs extends Component {
state = {
user: {
email: '',
password: ''
}
}
// 멀티 이벤트 핸들링 리스너
handleChange = (e) => {
const {name, value} = e.target
// user 상태 업데이트
this.setState({
user: {
...this.state.user,
[name]: value
}
})
}
render() {
const { user: { email, password } } = this.state;
return (
<>
<input
type="email"
name="email"
aria-label="계정 이메일"
value={email}
onChange={this.handleChange} />
<input
type="password"
name="password"
aria-label="계정 패스워드"
value={password}
onChange={this.handleChange} />
</>
)
}
}
React는 <textarea>
요소의 사용자가 입력한 내용을 value 속성
으로 받는다.
<textarea
value={this.state.value}
onChange={this.handleChange}
/>
React는 value 속성
을 사용해 초기값을 설정
<select
className="react-select"
value={this.state.value}
onChange={this.handleChange}
>
<option value="">선택</option>
// this.state.value가 "react"이면 초기 값으로 설정됨
<option value="react">리액트</option>
<option value="reactRouter">리액트 라우터</option>
<option value="redux">리덕스</option>
React는 <select>
요소에 다음의 2가지 설정이 요구된다.
1. multiple 속성
값은 true
2. vlaue 속성
값은 배열 데이터 유형으로 설정
<select
className="react-select"
// multiple 속성은 true
multiple={true}
// this.state.value가 배열(Array)데이터 형식 이여야함
value={this.state.value}
onChange={this.handleChange}
>
<option value="">선택</option>
<option value="react">리액트</option>
<option value="reactRouter">리액트 라우터</option>
<option value="redux">리덕스</option>
state = {
value : [], // 초기값 배열
}
handleChange(e) {
// select > option 요소 수집 후 배열 데이터로 변경
const options = Array.from(e.target.children)
// 사용자가 선택한 option filtering
const selectedOptions = options.filter(option => option.selected);
// filtering 된 option.value 값을 아이템으로 하는 새로운 배열 반환
const selectedOptionValue = selectedOption.map(option => option.value);
// 상태 업데이트
this.setState({value: selectedOptionValue});
}
컨트롤 되지 않은 컴포넌트는 React 외부에서 작동되는 것처럼 처리된다.
사용자가 폼 입력 컨트롤(input
, dropdown
등)에 입력하면 업데이트 된 정보가 React에서 별도 처리 과정 없이 요소에 바로 반영된다.
특별한 경우를 제외하고, 폼 컨트롤은 React에서 제어(Controlled)하는 것이 권장
<input type="file" />
이 컴포넌트는 프로그래밍 방식으로 값을 설정할 수 없고, 사용자에 의해 값이 설정되는 특별한 경우로 Uncontrolled 컴포넌트
이다.
컨트롤 할 수 없는 컴포넌트는 React가 아닌, DOM 자체에서 데이터를 다뤄야 한다.
Uncontrolled 컴포넌트
를 제어하기 위해 직접 DOM을 통해 요소의 사용자 입력값을 가져와 처리해야한다.
문제는 "가상 DOM에서 어떻게 실제 DOM에 접근할 것인가?"이다.
ref
속성은 컴포넌트가 렌더링 된 이후의 실제 DOM 노드나 React 요소에 접근해야할 때 사용하는 방법이다.
ref
속성을 활용하려면 먼저 React.createRef() 메서드를 사용해 참조 객체를 생성해야 한다.
생성 된 참조(Ref.)는 ref속성을 통해 DOM 노드 또는 React 요소를 가리킨다.
class FileInput extends Component {
// 참조 객체 생성
fileInput = React.createRef(null);
handleSubmit = (e) => {
e.preventDefault();
console.log(`선택된 파일: ${this.fileInput.current.files[0].name}`);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
/* React에서는 for 속성을 htmlFor로 사용 */
<label htmlFor="fileInput">
/* 참조 할 노드의 ref 속성에 참조 객체 연결 */
<input id="fileInput" type="file" ref={this.fileInput} />
</label>
</form>
)
}
}
ref
속성이 설정 된 DOM 요소는 ref.current
속성을 통해 접근가능
ref
속성 사용가능import React, {useRef} from 'react';
const FunctionalComponent = (props) => {
const divRef = useRef(null);
return (
<div ref={divRef}> ... </div>
)
}