reference! in React 와 Focus 구현

mgkim·2025년 1월 3일
0

react

목록 보기
22/36
post-thumbnail

올바른 ref 사용법

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;

React에서 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상태 없는 클래스 컴포넌트
2scrollTopscrollBottom 함수
3ref를 통한 DOM 요소 접근
4스타일링
5JSX 렌더링

학습 포인트

  1. ref 이해하기 ref={x => this.myDiv = x}
  2. 스크롤 속성 이해 :DOM에서 스크롤 위치를 조작
  3. React와 DOM 연동 :React는 일반적으로 상태 관리와 선언적 렌더링을 강조

기본 구문

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;

실습: ID, PW 검증 연습

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;

1. 상태와 Ref 선언

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();
}

상태(state):

id, password, confirmPassword로 입력값을 저장합니다.
errors는 각 필드의 검증 실패 메시지를 저장하는 객체입니다.

Ref:

idInputRef, passwordInputRef, confirmPasswordInputRef를 생성하여 입력 필드에 포커스를 이동할 수 있도록 설정합니다.

2. 입력값 변경 핸들러

handleChange = (e) => {
  const { name, value } = e.target;
  this.setState({ [name]: value });
};

사용자가 입력 필드에 값을 입력할 때 상태를 업데이트합니다.
name 속성을 기반으로 상태의 키를 동적으로 업데이트합니다.

3. 폼 제출 핸들러

-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("등록이 완료되었습니다!");
    }
  });
};

4. 렌더링

-폼 구성:

각각의 안에 이 포함되어 있으며, name, value, onChange를 통해 상태와 연결됩니다. ref를 이용하여 특정 입력 필드에 포커스를 이동할 수 있습니다.

-에러 메시지 표시:errors 상태에 메시지가 저장되어 있으면 해당 필드 아래에 빨간색으로 표시됩니다.

-버튼: "등록" 버튼을 클릭하면 handleSubmit 함수가 호출됩니다.

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>
  );
}
profile
@lala.love_garden.lala

0개의 댓글