react 실습
-cmd 명령프롬프트(관리자권한 실행)
->cd..(나가기) -> cd React(리액트 파일로 들어가기)
->npx -create-react-app 프로젝트이름
->code .으로 프로젝트 열기
->npm start로 프로그램 실행
component => JSX(javascript + XML)
-하나의 파일에 자바스크립트와 HTML을 동시에 자성
-재사용이 가능하고, 코드를 작은 규모로 관리할 수 있다
-생산성과 유지보수가 용이한 특징
-복합하고 동적인 웹어플리케이션에서 ui를 동적으로 나타내기 위해 많은 상태를 관리해야하는 부담이 생기는데 react가 이것을 해결해준다
react의 특징 => 선언적 방식
-프로그램이 어떤 방법으로 해야하는 지를 나타내기보다 무엇과 같은지를 설명하는 경우 선언형 방식이라고 한다
-리액트는 선언형 방식으로 작성
컴포넌트 만들기
-파일 확장자는 js, 컴포넌트는 단순 자바스크립트 함수
-컴포넌트 이름은 대문자로 시작해야함, html 코드를 리턴함
-반드시 하나의 루트 요소만 가져야 한다
-export를 이용하여 다른 파일로 내보내야됨 (ex) App.js)
props
-props를 이용하여 데이터를 컴포넌트 맞춤으로 보낼 수 있다
-컴포넌트사이 데이터를 전달할 수 있는 방법
import './App.css';
import {useState} from "react"; //상태관리 함수 추가
function App() {
// let counter = 0; 기존 방법으로 값을 변경, 리액트에서 사용X
// counter = counter + 1; 기존 방법으로 값을 변경, 리액트에서 사용X
const [counter, setCounter] = useState(0);
const increase =()=>{
setCounter(counter + 1);
};
const decrease =()=>{
setCounter(counter - 1);
};
return (
<div>
<div>{counter}</div>
<button onClick={increase}>증가 버튼</button>
<button onClick={decrease}>감소 버튼</button>
</div>
);
}
export default App;
스토리북(Storybook) : UI컴포넌트 개발 도구
데모용 코드를 작성하는 데 도움을 주고 공통적으로 사용될 컴포넌트를 팀원들과 편리하게 공유하는 도구로 활용
구성단위는 스토리(Story)
하나의 UI컴포넌트는 보통 하나 이상의 Story를 가짐
장점
-복잡한 로직 없이 독립적인 환경에서 컴포넌트를 개발할 수 있다
-재사용을 위한 컴포넌트들을 story에서 조합해 테스트할 수 있다
-컴포넌트들을 문서화 할 수도 있고 디자인 시스템에 적용해 피그마의 컴포넌트들과 동기화할 수 있다
npx -p storybook sb init 프로젝트이름 => 스토리북 프로젝트 생성
npm run storybook => 스토리북 프로젝트 시작
main.js : stories를 위한 config 설정
preview.js : 모든 story들에 글로벌하게 적용될 포맷 세팅
스토리 기본구조
Export default {
Title : 스토리북에 올릴 component 폴더 계층 구조,
Component : 스토리를 만들 컴포넌트 이름
}
Export const 스토리이름 = () => 해당스토리에서 테스트할 인자가 담긴 컴
포넌트
import React, { Component } from 'react';
import PropTypes from "prop-types";
export function Text({children, color, italic, underline}){
const style={
color : color,
fontStyle : italic? "italic" : "normal",
textDecoration : underline? "underline" : "none",
};
return<span style={style}>{children}</span>;
};
Text.PropTypes = {
children : PropTypes.string.isRequired,
color : PropTypes.string,
italic : PropTypes.bool,
underline : PropTypes.bool,
};
Text.defaultProps = {
color : "black",
italic : false,
underline : false,
};
-Text.stories.js
import React, { Component } from 'react';
import { Text } from './Text';
export default{
title : "Text",
component : Text,
};
const TEST_TEXT = "Story Text Test";
export const Default = ()=><Text>{TEST_TEXT}</Text>;
export const Red = ()=><Text color="red">{TEST_TEXT}</Text>;
export const Italic = ()=><Text italic>{TEST_TEXT}</Text>;
export const Underline = ()=><Text underline>{TEST_TEXT}</Text>;
Input 프로젝트
-Input.jsx
import React, { Component } from 'react';
import PropTypes from "prop-types";
class Input extends Component{
constructor(props){
super(props);
this.setRef = this.setRef.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e){
const{name, onChange} = this.props;
if(onchange){
onChange(name, e.target.value);
}
}
componentDidMount(){
if(this.props.autoFocus){
this.ref.focus();
}
}
componentDidUpdate(){
if(this.props.autoFocus){
this.ref.focus();
}
}
setRef(ref){
this.ref = ref;
}
render(){
const {errorMessage, label, name, value, type, onFocus} = this.props;
return(
<label>
{label}
<input>
id = {"input_${name}"}
ref = {this.setRef}
onChange = {this.handleChange}
onFocus = {onFocus}
value = {value}
type = {type}
</input>
{errorMessage && <span className="error">{errorMessage}</span>}
</label>
);
}
}
Input.PropTypes = {
type: PropTypes.oneOf(["text", "number", "price"]),
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
errorMessage: PropTypes.string,
label: PropTypes.string,
onChange: PropTypes.func,
autoFocus: PropTypes.bool,
}
Input.defaultProps = {
onChange: () => {},
onFocus: () => {},
autoFocus: false,
type: "Text",
}
export default Input;
-Input.stories.js
import React, { Component } from 'react';
import Input from "./Input";
export default{
title: "Input",
component : Input,
}
export const Label = ()=><input name="name" label="이름: "/>;

현재 어플리케이션을 통한 실행방법보다 리액트의 다양한 프레임워크들을 통해 작업들이 이루어지는 추세라는 걸 알았기 때문에 리액트를 공부하는 부분이 중요하다는 걸 알았다. 특히 PWA라는 프레임워크는 어플리케이션 없이 어플리케이션에서 가능한 많은 부분들을 실행 가능하게 해준다는 점에서 아주 효용성이 크다고 들었기 때문에 이런부분들이 중요하다고 생각되었다. 하지만 구동하는 부분까지 따라는 갈 수 있었지만 문ㅂ접이라던가 어떻게,왜에 대해서는 너무나도 부족한 걸 알았다. 그저 따라가기 급급한 부분들이 많기 때문에 개선할 필요가 있다.
여러가지 실스부분들이나 잘 모르겠는 부분, 리액트의 활용법들을 찾아보고 물어보고 사용해봐야 한다. 지극히 간단한 구동방식을 실험해보는데도 아직은 힘겨워하기 때문에 많이 해 볼 수 밖에 없다. 시간이 많이 남지 않았음을 이해하고 시간을 계속 더 투자할 필요가 있다.
이제 2달의 시간이 남았다. 내가 뭐라도 할 수 있나라는 부분에 대해서 냉정하게 생각해볼 필요가 있다. 내가 가고싶은 가야만할 방향에 대해서는 생각해본 부분들이 있기때문에 시간을 쏟을 필요가 있다. 앞으로도 계속 배워야 하겠지만 편안한 환경에서 배울 수 있는 시간은 많지 않다. 시간을 잘 활용하자.