React - 2. 구구단게임

원종현·2021년 4월 14일
0

react

목록 보기
2/5
post-thumbnail

2021.04.14

React 구구단 만들기

바뀌는 것은 state로 등록을 해준다.

직접 수동으로 바꿀 값들만 state로 만들어 준다.

안 바뀌는 것은 tag로 만들어 둔다.

// 구구단 컴포넌트 만들기

class GuGuDan extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            first: Math.ceil(Math.random() * 9), //첫 번째 랜덤 숫자
            second: Math.ceil(Math.random() * 9), // 두 번째 랜덤 숫자
            value: '', //input 값
            result: '', //결과 값
        };
    }

    onSubmit = (e) => {
        e.preventDefault();
        if(parseInt(this.state.value) === this.state.first * this.state.second) {
        this.setState({
            result: `${this.state.value} : 정답입니다.`
            first: Math.ceil(Math.random() * 9),
            second: Math.ceil(Math.random() * 9),
            value: '',
        })
        } else {
            this.setState({
                result: '땡',
                value: '',
            });
        }
    };

    onChange = (e) => {
        this.setState({ value: e.target.value })
    };

    render() {
        return (
            <div>
                <div>{this.state.first} 곱하기 {this.state.second}?</div> //{}안에는 js를 사용할 수 있다.
                <form onSubmit={this.onSubmit}>
                    <input type="number" value={this.state.value} onChange={this.onChange} />
                    <button type="submit">입력</button>
                </form>
                <div>{this.state.result}</div>
            </div>
        );
    }
}

ReactDOM.render(<GuGuDan />, document.querySelector('#root'));

태그 사이 컨텐츠 영역에 {}를 사용해서 js문법을 사용할 수 있다.

중괄호 사이에 js문법 작성

이벤트리스너는 함수(메서드)로 빼서 따로 작성한다.

Fragment & 기타 팁

  • React에서는 하나의 컴포넌트가 여러 개의 엘리먼트들을 반환하는 경우가 흔하다.하지만 JSX문법을 사용할 때, return문 안에는 반드시 하나의 최상위 태그가 있어야 한다. 이는 React가 하나의 컴포넌트만 리턴할 수 있기 때문이다.
  • 이때 쓸데없는
    가 추가 된다.
  • Fragment는 별도의 노드를 추가하지 않고 여러 자식을 그룹화할 수 있게 해주므로 위 문제를 해결해 준다.
  • <React.Fragment></React.Fragment>로 감싸준다.
  • 단축 문법 : 위 태그 대신에 <></>로 감싸준다. (Fragments를 선언하는 더 짧고 새로운 문법, 빈 태그와 같다.)
  • react 공식문서에서 아래 예시를 그대로 가져왔다.
    //ex)
    class Table extends React.Component {
        render() {
            return (
            <table>
                <tr>
                <Columns />
                </tr>
            </table>
            );
        }
    }

    class Columns extends React.Component {
        render() {
            return (
            <div>
                <td>Hello</td>
                <td>World</td>
            </div>
            );
        }
    }

    //<Table /> html 출력 결과
    <table>
        <tr>
            <div>
            <td>Hello</td>
            <td>World</td>
            </div>
        </tr>
    </table>
    // 쓸 데 없는 div가 생기는 문제를 fragment가 해결해 준다.
    class Columns extends React.Component {
        render() {
            return (
            <React.Fragment>
                <td>Hello</td>
                <td>World</td>
            </React.Fragment>
            );
        }
    }
    //단축 문법
    class Columns extends React.Component {
        render() {
            return (
            <>
                <td>Hello</td>
                <td>World</td>
            </>
            );
        }
    }
    //fragment를 적용한 출력 결과
    <table>
        <tr>
            <td>Hello</td>
            <td>World</td>
        </tr>
    </table>
  • 기능을 함수로 따로 구현할 경우 화살표 함수 사용해야 한다. (function, 화살표 함수는 this의 값이 다르다.)
  • constructor(props){super(props);},this 는 작성하지 않아도 된다.

함수형 setState

  • setState안에 새로운 state를 return해주는 함수를 넣어준다.
  • 예전 값(현재 값)과 새로운 값(미래에 바뀌는 값)을 구분할 수 있다는 장점이 있다.
  • 함수를 이용하면 prevState를 사용할 수 있다는 장점이 있다.
    this.setState((prevState) => {
        return {
            result: `${prevState.value} : 정답입니다.`
            first: Math.ceil(Math.random() * 9),
            second: Math.ceil(Math.random() * 9),
            value: '',
        };
    })

    //prevState = 예전 state
  • setState는 비동기 방식이다.
  • 예전 state가 새로운 state에 영향을 미칠경우 객체형태가 아닌 함수형태로 작성을 해준다.
  • setState를 하면 render()함수가 다시 실행된다. (state가 바뀔 때마다 렌더링이 다시 된다는 것이다.)

ref

  • 포커스, 텍스트 선택영역, 혹은 미디어의 재생을 관리할 때
  • 애니메이션을 직접적으로 실행시킬 때
  • DOM에 직접 접근하고 싶을 때
    this.Input = React.createRef();
    
    focusInput = () => {
        this.Input.current.focus();
    }

    render() {
        return (
            <>
                <input type="text" ref={this.Input} />
            </>
        )
    }

React Hook

  • react에서 최근 추천하는 방법 (이제는 class대신 hooks사용을 권장한다.)
  • Hook을 이용하여 Class를 작성할 필요 없이 State와 여러 React의 기능을 사용할 수 있다.
  • Hook은 함수 컴포넌트에서 React State와 생명주기 기능을 연동할 수 있게 해주는 함수이다.
    const GuGuDan = () => {
        const [first, setFirst] = React.useState(Math.ceil(Math.random() * 9));
        const [second, setSecond] = React.useState(Math.ceil(Math.random() * 9));
        const [result, setResult] = React.useState('');
        const [value, setValue] = React.useState('');
        const inputRef = React.useRef(null);

        const onSubmit = (e) => {
            e.preventDefault();
            if(parseInt(value) === first * second) {
                setResult(value + '정답입니다.');
                setFirst(Math.ceil(Math.random() * 9));
                setSecond(Math.ceil(Math.random() * 9));
                setValue('');
                inputRef.current.focus();
            } else {
                setResult('땡');
                setValue('');
                inputRef.current.focus();
            }
        }

        const onChange = (e) => {
            setValue(e.target.value);
        };

        return (
            <>
                <div>{first} 곱하기 {second}?</div>
                <form onSubmit={onSubmit}>
                    <input ref={inputRef} type="number" value={value} onChange={onChange} />
                    <button type="submit">입력</button>
                </form>
                <div>{result}</div>
            </>
        )
    }

    //React.useState('초기값을 넣어준다.');
  • 함수형 컴포넌트에서 state값이 바뀌면 함수 컴포넌트 자체가 다시 렌더링된다.
  • 클래스형 컴포넌트에서는 state값이 바뀌면 render()함수만 다시 렌더링된다.
  • react에서 html태그에 class이름을 부여할 경우 class키워드를 사용할 수 없다 class 대신에 className 키워드를 사용
  • 마찬가지로 for속성 대신에 htmlFor 키워드를 사용한다.
profile
프론트엔드 엔지니어를 목표로 공부하는 중입니다!.

0개의 댓글