2020/08/18 - [Web프론트엔드/리액트] - [React] 리액트 개발환경 구축
2020/08/21 - [Web프론트엔드/리액트] - Visual Studio Code 및 React 관련 플러그인 설치
2020/09/09 - [Web프론트엔드/리액트] - [React] 리액트 테스트 앱 생성 및 수정
2020/09/11 - [Web프론트엔드/리액트] - [React] 리액트에서 사용하는 JSX
2020/09/11 - [Web프론트엔드/리액트] - [React] 리액트의 컴포넌트를 알아보자
2020/09/15 - [Web프론트엔드/리액트] - [React] 컴포넌트의 데이터 관리 ① - props 프로퍼티
2020/09/19 - [Web프론트엔드/리액트] - [React] 컴포넌트의 데이터 관리 ② - state 스테이트
2020/09/21 - [Web프론트엔드/리액트] - [React] 컴포넌트의 데이터 관리 ③ - 콜백 함수
2020/09/22 - [Web프론트엔드/리액트] - [React] 컴포넌트의 형태를 분류해보자
2020/09/24 - [Web프론트엔드/리액트] - [React] 컴포넌트의 Lifecycle 생명주기 함수 - 이론
2020/09/24 - [Web프론트엔드/리액트] - [React] 컴포넌트의 Lifecycle 생명주기 함수 - 실습
2020/09/28 - [Web프론트엔드/리액트] - [React] 컴포넌트의 DOM 관련 이벤트 - 무한 scroll 예제
지금까지 리액트 관련 글을 쓰면서 배웠던 것들을 이용해 Input 컴포넌트를 만들어 보겠습니다.
최대한 배웠던 기초적인 것들만 이용했으며, 약간의 자바스크립트 관련 로직도 나옵니다. 먼저 실행화면을 보시죠!
앞으로 만들 InputComponent가 두 개 들어가 있습니다. 아이디와 비밀번호 창인데 한글이 입력되면 에러 메시지가 나오며, 비밀번호 창은 방금 입력한 것을 뺀 나머지는 전부 가려져 있습니다. 그럼 App.js부터 가시죠!
// ..\test_project\src\App.js
import React, { Component } from "react";
import InputComponent from "./components/InputComponent";
class App extends Component {
// 하위 컴퍼넌트에서 불러오는 콜백 함수
chagneInput(name, value) {
console.log(`chagneInput() name : ${name} , value : ${value}`);
}
render() {
return (
<div>
<InputComponent
label="아이디 : "
name="id"
value="아이디를 입력하세요"
errorMessage="한글 입력중..."
autoFocus={true}
/>
<br />
<InputComponent
label="비밀번호 : "
name="pass"
//type="password"
value="비밀번호를 입력하세요"
errorMessage="한글 입력중..."
onChange={this.chagneInput}
/>
</div>
);
}
}
export default App;
InputComponent 두 개 배치되어 있습니다. 중요 프로퍼티로는 name, value, type, onChange 등이 있습니다. changeInput() 콜백 함수는 하위 컴포넌트에서 불러주므로 다양한 방법으로 응용이 가능합니다.
자 다음은 드디어 오늘의 주인공인 InputComponent.jsx 보시겠습니다.
// ..\test_project\src\components\InputComponent.jsx
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
class InputComponent extends PureComponent {
constructor(props) {
super(props);
this.state = {
value: props.value, // 상위 프로퍼티로 초기화
isError: false, // 입력 오류가 있는지
isFirst: true, // 처음 입력창 포커스
};
// 콜백 함수 바인딩
this.setRef = this.setRef.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleFocus = this.handleFocus.bind(this);
}
// ref 프로퍼티 연결
setRef(ref) {
this.ref = ref;
}
// 입력창 변경 이벤트
handleChange(e) {
const { name, onChange } = this.props;
console.log(
`handleChange() name : ${name} , e.target.value : ${e.target.value}`
);
// 콜백 함수가 있을 경우
if (onChange) {
// 한글 입력 체크
const pattern_kor = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/;
let checkError = false;
if (pattern_kor.test(e.target.value)) checkError = true;
// 비밀번호 입력창은 문자 치환
let strValue = String(e.target.value);
if (name === "pass") {
for (var i = 0; i < strValue.length - 1; i++) {
strValue = strValue.replace(strValue[i], "*");
}
}
// 변경된 스테이트 값
this.setState({ isError: checkError, value: strValue });
// 상위 컴포넌트 콜백 함수 실행
onChange(name, e.target.value);
}
}
// 입력창에 포커스
handleFocus(e) {
// 처음 포커스시에는 입력창 초기화
if (this.state.isFirst) {
this.setState({ value: "", isFirst: false });
}
}
// 컴포넌트 마운트
componentDidMount() {
// 포커스 맞추기
if (this.props.autoFocus) {
this.ref.focus();
}
}
render() {
// 프로퍼티 받아서 화면 출력
const { label, name, type, errorMessage } = this.props;
return (
<label>
{label}
<input
id={`input_${name}`}
value={this.state.value}
type={type}
ref={this.setRef}
onChange={this.handleChange}
onFocus={this.handleFocus}
/>
{this.state.isError && errorMessage}
</label>
);
}
}
InputComponent.propTypes = {
label: PropTypes.string,
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
type: PropTypes.oneOf(["text", "password", "number", "price"]),
autoFocus: PropTypes.bool,
errorMessage: PropTypes.string,
onChange: PropTypes.func,
onFocus: PropTypes.func,
};
InputComponent.defaultProps = {
value: "",
type: "text",
autoFocus: false,
onChange: () => {},
onFocus: () => {},
};
export default InputComponent;
소스가 길어 보이지만 특별한 것은 없고, 이때까지 배운 내용들에서 사용하는 변수가 조금 늘어난 정도입니다. 주석을 달아놓았으니 실습을 해보시면 더욱 이해가 잘 되시라 생각하고, 특히 handleChange() 부분이 중요합니다.
하지만 이번 InputComponent 소스는 리액트의 개발 철학인 컴포넌트의 재활용 측면에서는 잘 못 설계되어 있습니다. 앞으로 배울 리액트의 다양한 기능으로 더욱더, 재활용할 수 있는 컴포넌트를 만들어 갈 것입니다.
오늘은 여기까지 입니다. 이때까지 배운 내용으로만 실습한 것이라 다소 무리가 있는 소스이지만, 리액트의 기초적인 부분을 확실히 복습할 수 있는 기회라 생각합니다.
그럼 오늘도 참 쉽죠?
2020/09/29 - [Web프론트엔드/리액트] - [React] 리액트 기초 관련 글 정리 (개발환경, 데이터, 컴포넌트 등)
'웹 프론트엔드 > React 리액트 (기초)' 카테고리의 다른 글
[React] 재활용 가능한 기본적인 Input 컴포넌트 (0) | 2020.10.06 |
---|---|
[React] 리액트 기초 관련 글 정리 (개발환경, 데이터, 컴포넌트 등) (0) | 2020.09.29 |
[React] 컴포넌트의 DOM 관련 이벤트 - 무한 scroll 예제 (0) | 2020.09.28 |
[React] 컴포넌트의 Lifecycle 생명주기 함수 - 실습 (0) | 2020.09.24 |
[React] 컴포넌트의 Lifecycle 생명주기 함수 - 이론 (0) | 2020.09.24 |
댓글