22.03.17(목) props,state,ref

luckygamza·2022년 3월 17일
0

TIL

목록 보기
16/21

props

properties를 줄인 표현으로 컴포넌트의 속성을 설정할 때 사용하는 요소이다.
props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다.
props를 바꾸려면 부모 컴포넌트에서 바꾸어 주어야 한다.

props의 값은 컴포넌트 함수의 파라미터로 받아와 사용할 수 있다.

props 사용 예시

부모 컴포넌트에서 자식 컴포넌트의 props를 설정하기

const App = () => {
  return <MyComponent name="seyeon" age="26"></MyComponent>;
};

자식 컴포넌트에서 props값 사용하기

const MyComponent = (props) => {
  return (
    <>
      <div>내 이름은 {props.name} 입니다</div>
      <div>나이는 {props.age}세입니다</div>
    </>
  );
};

props 기본값 설정 - defaultProps , 타입 지정 - propTypes

/* props 기본값 설정 */
MyComponent.defaultProps = {
  name: '기본이름',
};
/* props 타입 지정 */
MyComponent.defaultProps = {
  age: PropTypes.number.isRequired,
};

비구조화 할당 문법을 이용해 props 값 분해하여 사용하기

const MyComponent = ({ name, age }) => {
  return (
    <>
      <div>내 이름은 {name} 입니다</div>
      <div>나이는 {age}세입니다</div>
    </>
  );
};

비구조화 할당 문법(구조 분해 문법) = 객체에서 값을 추출하는 문법
함수의 파라미터로 객체인 props가 넘어왔으니, 이 값을 분해하여 사용 가능.

State

리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값을 의미한다.

클래스형 컴포넌트에서 State를 사용하기

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0,
    };
  }
  render() {
    const { number } = this.state;
    return (
      <div>
        <h1>{number}</h1>
        <button
          onClick={() => {
            this.setState({ number: number + 1 });
          }}
        >
          +1
        </button>
      </div>
    );
  }
}

위와 같이 생성자 안에서 this.state ={}를 정의해주어도 되고, 생성자 밖에서 state= {} 와 같이 state를 정의해주어도 된다.
클래스형 컴포넌트에서 state 초기값은 객체 형태를 할당해 주어야 한다.
이 후, this.setState({ number: number + 1}); 와 같이 setState를 호출하여 state를 변경해줄 수 있다.

this.setState에 객체 대신 함수 인자 전달하기

		onClick={() => {
            this.setState({ number: number + 1 });
            this.setState({ number: number + 1 });
          }}

위 코드는 number를 +2씩 증가시키지 않는다.
이유는 this.setState를 사용한다고 해서 state값이 바로 바뀌지는 않기 때문이다.
state를 바로 바꾸어 주려면 this.setState에 인자를 함수를 넣어주면 된다.

함수인자를 넣는 형식은 다음과 같다.

			this.setState((prevState,props) => { //prevState : 기존 state를 인자로 넣어줌. props는 사용하지 않는다면 생략 가능
              return {
                // 업데이트 하고 싶은 내용
              }
            });

위의 number를 증가시키는 예시를 함수인자를 사용한 방식으로 바꾸어보면 다음과 같다.

		onClick={() => {
            this.setState({ number: number + 1 });
            this.setState((prevState) => {
              return {
                number: prevState.number + 1,
              };
            });
          }}

함수형 컴포넌트에서 state를 사용하기 - useState

리액트 16.8 이전 버번에서는 함수형 컴포넌트에서 state를 사용할 수 없었지만, 16.8 이후부터는 useState라는 함수를 사용해서 함수형 컴포넌트에서도 state를 사용할 수 있게 되었다.

import React, { useState } from 'react';
const Say = () => {
  const [message, setMessage] = useState(''); //배열 비구조화 할당
  const onClickEnter = () => setMessage('안녕하세요!');
  const onClickLeave = () => setMessage('안녕히 가세요!');

  return (
    <div>
      <button onClick={onClickEnter}>입장</button>
      <button onClick={onClickLeave}>퇴장</button>
      <h1>{message}</h1>
    </div>
  );
};
export default Say;

const [message, setMessage] = useState('');

useState의 함수의 인자에는 State의 초기값을 넣어준다. 클래스형 컴포넌트 때와 달리 useState를 이용한 State의 초기값은 객체 뿐만이 아니라, 숫자 , 문자열 등도 모두 자유롭게 가능하다.
useState 함수의 반환값은 배열인데, 배열의 첫번째 원소는 현재 상태이고, 두번째 원소는 상태를 바꾸어주는 함수(setter 함수)이다.
즉 위에서 message가 현재 상태, setMessage가 세터함수이다.

state를 변경할 때 주의할 점

클래스형 컴포넌트든 함수형 컴포넌트든 마찬가지로 state를 변경할 때는 state를 직접 건드려서 변경하면 안된다.

// 클래스형 컴포넌트의 경우
this.state.number +=1; // 안됨
this.setState({number : number+1}); //이렇게 해야 함.

// 함수형 컴포넌트의 경우
const [number,setNumber] = useState(0);
number+=1 // 안됨
setNumber(number+1); //이렇게 해야함.

클래스형 컴포넌트는 setState()를 이용해서 변경해야하고,
함수형 컴포넌트는 useState를 통해 전달받은 setter 함수를 이용해서 변경해야 한다.

ref

ref: 리액트 프로젝트 내부에서 DOM에 달아놓을 수 있는 이름.
ref는 DOM 요소를 꼭 직접적으로 건드려야 할때 사용한다.
예를 들어 DOM 요소의 background-color를 바꾸는 작업은 state 변경을 이용해 DOM요소의 className만 바꾸어주면 가능하다.굳이 ref를 붙여서 DOM을 직접 조작해야 할필요가 없는 작업이다.
하지만 특정 input에 focus 주기, 스크롤 박스 조작하기, Canvas 요소에 그림그리기 등의 작업은 DOM요소에 직접 접근해야 하는 작업들이다. 이럴 때 ref를 사용해서 DOM요소에 직접 접근한다.

<input ref={(ref)=>{this.inputA=ref}} />

위와 같이 콜백 함수로 ref를 달아줄 수 있다. 이후, 다른 코드에서 this.inputA를 불러와 this.inputA.focus() 와 같이 input DOM 요소를 직접 조작할 수 있다.

DOM요소 뿐만 아니라, 컴포넌트에도 ref를 사용할 수 있다. 사용방법은 똑같다.

<MyComponent ref={(ref)=>{this.componentX=ref}} />


ref를 이용해서 위와 같은 스크롤 박스 조작 기능을 만들 수 있다.

0개의 댓글

관련 채용 정보