React.createRef()를 활용하면 코드를 더 직관적이고 안정적
import { Component } from "react";
class MyComponent extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef(); // Ref 생성
}
state = {
message: ""
};
handler = () => {
const node = this.myRef.current; // Ref의 현재 DOM 노드에 접근
if (node) {
node.focus(); // 포커스를 전달
}
};
render() {
return (
<>
<input
ref={this.myRef} // Ref 연결
onChange={e => this.setState({ message: e.target.value })}
/>
<button onClick={this.handler}>포커스전달</button>
</>
);
}
}
function App() {
return <MyComponent />;
}
export default App;
ref
사용법 정리구분 | 설명 | 코드 예제 |
---|---|---|
React.createRef() | 클래스형 컴포넌트에서 ref 를 생성하는 안전하고 권장되는 방식 | this.myRef = React.createRef(); |
useRef | 함수형 컴포넌트에서 ref 를 생성하는 최신 방식 | const myRef = useRef(null); |
DOM 접근 | ref 를 통해 현재 DOM 노드에 접근 | this.myRef.current 또는 myRef.current |
포커스 전달 | ref 를 통해 DOM 요소에 포커스를 설정하는 방법 | myRef.current.focus(); |
ref 연결 | ref 를 특정 DOM 요소에 연결 | <input ref={this.myRef} /> |
ref={x => { this.myRef = x; console.log(x); }}
constructor(props) {
super(props);
this.myRef = React.createRef(); // Ref 생성
}
ref={this.myRef} // Ref 연결
const node = this.myRef.current; // Ref의 현재 DOM 노드에 접근
React.createRef() 사용: ref를 더 명확하고 안전하게 사용하도록 수정.
myRef.current 접근: React.createRef()로 생성한 ref 객체의 current 속성을 통해 DOM 노드에 접근.
안정성 추가: 버튼 클릭 시 node가 존재하는지 확인 후 동작하도록 조건문을 추가
수정된 코드를 실행하면, 버튼을 클릭할 때 input 요소에 포커스가 정상적으로 전달됨
객체 비구조화해준 캡처내용
함수2개 쓰고, 이벤트핸들러설정했고, 상태변수로는 불가능한 코딩을 ref함수로는 가능하다
번호 | 주요 코드 구성 요소 |
---|---|
1 | 상태 없는 클래스 컴포넌트 |
2 | scrollTop 와 scrollBottom 함수 |
3 | ref 를 통한 DOM 요소 접근 |
4 | 스타일링 |
5 | JSX 렌더링 |
import { Component } from "react";
class App extends Component {
render() {
return (
<div>
ID: <input type="text" /><br />
PW: <input type="password" /><br />
PW: <input type="password" /><br />
<button type="submit">등록</button>
</div>
);
}
}
export default App;
1 등록 버튼을 클릭하면,
2 ID, PW 입력창에 값 입력 여부를 체크해서 적절한 메시지를 출력
3 PW 입력창에 값 일치 여부를 체크해서 적절한 메시지를 출력
4 문제가 있는 입력창으로 포커스를 이동하도록
아래의 App.js 코드를 완성해 보세요.
import { Component } from "react";
class App extends Component {
render() {
return (
<div>
ID: <input type="text" /><br />
PW: <input type="password" /><br />
PW: <input type="password" /><br />
<button type="submit">등록</button>
</div>
);
}
}
export default App;
constructor(props) {
super(props);
this.state = {
id: "",
password: "",
confirmPassword: "",
errors: {
id: "",
password: "",
confirmPassword: "",
},
};
this.idInputRef = React.createRef();
this.passwordInputRef = React.createRef();
this.confirmPasswordInputRef = React.createRef();
}
id, password, confirmPassword로 입력값을 저장합니다.
errors는 각 필드의 검증 실패 메시지를 저장하는 객체입니다.
idInputRef, passwordInputRef, confirmPasswordInputRef를 생성하여 입력 필드에 포커스를 이동할 수 있도록 설정합니다.
handleChange = (e) => {
const { name, value } = e.target;
this.setState({ [name]: value });
};
사용자가 입력 필드에 값을 입력할 때 상태를 업데이트합니다.
name 속성을 기반으로 상태의 키를 동적으로 업데이트합니다.
-e.preventDefault()를 호출하여 폼의 기본 제출 동작을 막습니다.
-errors 객체를 초기화한 후 각 입력값을 검증합니다.
-입력값이 비어 있거나 비밀번호가 일치하지 않으면 해당 에러 메시지를 설정하고, Ref를 통해 해당 입력창에 포커스를 이동합니다.
-검증이 통과되면 "등록이 완료되었습니다!"라는 메시지를 표시합니다.
handleSubmit = (e) => {
e.preventDefault();
const { id, password, confirmPassword } = this.state;
let errors = {
id: "",
password: "",
confirmPassword: "",
};
let focusField = null;
if (!id.trim()) {
errors.id = "ID를 입력하세요.";
focusField = this.idInputRef;
} else if (!password.trim()) {
errors.password = "비밀번호를 입력하세요.";
focusField = this.passwordInputRef;
} else if (password !== confirmPassword) {
errors.confirmPassword = "비밀번호가 일치하지 않습니다.";
focusField = this.confirmPasswordInputRef;
}
this.setState({ errors }, () => {
if (focusField) {
focusField.current.focus();
} else {
alert("등록이 완료되었습니다!");
}
});
};
각각의 안에 이 포함되어 있으며, name, value, onChange를 통해 상태와 연결됩니다. ref를 이용하여 특정 입력 필드에 포커스를 이동할 수 있습니다.
render() {
const { id, password, confirmPassword, errors } = this.state;
return (
<div>
<form onSubmit={this.handleSubmit}>
<div>
<label>
ID:
<input
type="text"
name="id"
value={id}
onChange={this.handleChange}
ref={this.idInputRef}
/>
</label>
{errors.id && <div style={{ color: "red" }}>{errors.id}</div>}
</div>
<div>
<label>
Password:
<input
type="password"
name="password"
value={password}
onChange={this.handleChange}
ref={this.passwordInputRef}
/>
</label>
{errors.password && (
<div style={{ color: "red" }}>{errors.password}</div>
)}
</div>
<div>
<label>
Confirm Password:
<input
type="password"
name="confirmPassword"
value={confirmPassword}
onChange={this.handleChange}
ref={this.confirmPasswordInputRef}
/>
</label>
{errors.confirmPassword && (
<div style={{ color: "red" }}>{errors.confirmPassword}</div>
)}
</div>
<button type="submit">등록</button>
</form>
</div>
);
}