🟥 Props

 

properties를 줄인 표현으로 컴포넌트의 속성을 설정할 때 사용합니다.

props값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있습니다.

컴포넌트의 필수 props를 지정하거나 props의 타입(type)을 지정할 때는 propTypes를 사용합니다.

 

App.js

...
  return <MyComponent name="리액트" age={10}/>;
...

 

MyComponent.js

import PropTypes from 'prop-types';  // PropTypes 사용을 위해 추가

const MyComponent = {name, age}=> {
  return <div> 안녕하세요, 제 이름은 {name}입니다. 제 나이는 {age}입니다.</div>;
};

// defaultProps 설정 방법
MyComponent.defaultProps = {
  name : '지상렬'
};

// PropTypes지정 방법
MyComponent.propTypes = {
  name : PropTypes.string
  age : PropTypes.number.isRequired  // 필수 값 isRequired
};

export default MyComponent;

 

defaultProps와 propTypes 지정은 필수는 아니지만, 대규모 어플리케이션 개발 프로젝트 진행시 또는 협업시 개발 능률 향상을 위해 사용을 권장합니다.

 

 

🟥State

컴포넌트 내부에서 바뀔 수 있는 값을 의미합니다.

props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며,

컴포넌트 자신은 해당 props를 읽기전용으로만 사용할 수 있습니다.

 

props를 바꾸려면 부모 컴포넌트에서 바꾸어 주어야 합니다.

❗ props를 사용한다고 해서 값이 무조건 고정되는건 아닙니다.
부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하고,
자식 컴포넌트에서 특정 이벤트가 발생했을 때 부모 컴포넌트의 메서드를 호출하면 props도 유동적으로 사용할수 있습니다.

 

 

클래스형 컴포넌트에서 state 초깃값은 객체 형태로 넣어주어야 합니다.

🔶 setState

this.setState를 사용할 때는 함수를 인자로 넣을수도 있습니다.

형식은 다음과 같습니다

this.setState((prevState, props) => {
  return {
    // 업데이트 하고싶은 내용
  }
});

prevState는 기존 상태이고, props는 현재 지니고 있는 props를 가리킵니다.

만약 업데이트 과정에서 props가 필요하지 않다면, 생략 가능합니다.

 

class Counter extends Component {
	state = {
	  number: 0;
	}
	
	return() {
	  ...
	  <button onClick={() => {
	    this.setState(prevState => {
	      return {
	        number : prevState.number+1
	      };
	    });
	    // 위 코드와 아래 코드는 완전히 똑같은 기능을 합니다. 
	    // 아래 코드는 함수에서 바로 객체를 반환한다는 의미입니다.
	    this.setState(prevState => ({
	      number: prevState.number+1
	    }));
	  ... 
	  }
	}
}

 

onClick에서 두번째로 this.setState함수를 사용할 때는 화살표 함수에서 바로 객체를 반환하도록 했기 때문에 prevState ⇒ ({ }) 와 같은 형태로 코드가 이루어집니다.

 

this.setState의 두 번째 파라미터로는 콜백함수를 등록해 작업을 처리할 수 있습니다.

 

 

클래스형 컴포넌트에서 setState를 사용하며, 함수형 컴포넌트에서는 Hook중 하나인 useState를 사용합니다. 

 

🔶 useState

useState 함수의 인자에는 상태의 초깃값을 넣어 줍니다.

클래스형 컴포넌트는 초깃값을 무조건 객체 형태로 넣어주어야 하지만,

함수형 컴포넌트의 초기값의 형태가 자유롭습니다.

 

함수를 호출하면 배열이 반환되는데, 첫 번째 원소는 현재의 상태이고, 두 번째 원소는 상태를 변경해주는 함수입니다.

이 함수를 세터(Setter)라 부릅니다.

 

그리고 배열 구조분해 할당을 통해 자유롭게 네이밍이 가능합니다.

아래는 avengers와 setAvengers로 네이밍 한 예입니다.

let [avengers, setAvengers] = useState(["Spider", "Hulk", "Thor"]);

return() {
  ...
  <button onClick={() => {
    // state 안바뀜
    avengers[0] = "Ironman";
    setAvengers(avengers);  	    // state 안바뀜

    let copy = avengers;
    copy[0] = "Ironman";
    setAvengers(copy);            // 마찬가지로 state 안바뀜

    let copy = [...avengers];
    copy[0] = "Spiderman";
    setAvengers(copy);            // avengers = ["Spiderman", "Hulk", "Thor"]
  }}>
  버튼
  </button>
  ... 
}

state 변경 함수는 setAvengers는 ( ) 소괄호 안에 넣은걸로 기존 state를 갈아치웁니다.

 

🔶 state 사용시 주의사항

state값을 바꾸어야 할 때는 setState 혹은 useState를 통해 전달받은 세터함수를 사용해야 합니다.

 

❗배열이나 객체의 state 변경

state가 array나 object면 독립적 카피본을 만들어서 수정해야 합니다.

array도 결국 object입니다.

백날 데이터를 변경해봤자, 변수에 저장되어있는 객체를 가리키는 주소값은 달라지지 않기 때문입니다.

 

 

배열은 배열의 내장함수를 활용하는 방법도 있습니다.

const object = { a:1, b:2, c:3 };
const nextObject = {...object, b: 4}; // 사본을 만들어서 b값만 덮어쓰기


const array = [
  { id:1, value: true },
  { id:2, value: true },
  { id:3, value: false}
];

let nextArray = array.concat({ id: 4}); // 새항목 추가
nextArray.filter(item => item.id !== 2) // id가 2인 항목 제거
nextARray.map(item => item.id === 1 ? {...item, value: false} : item); //id가 1인 항목의 value를 false로 설정

+ Recent posts