운영진 스터디 - 2~3주차

SSO·2022년 2월 7일
0

LikeLion10th

목록 보기
1/16
post-thumbnail

2주차에는 JSX 문법과 state/props에 대해 배웠다 !

JSX

→ JavaScript를 확장한 문법으로 js 코드 안에서 ui관련 작업을 할 수 있다고 한다! 일반 html 태그를 사용해 가독성이 좋고 js로직 사용이 가능하기 때문에 활용도도 높다 !

  • 특징 요약
    • html 태그를 사용한다.
    • 그러므로 가독성이 좋다!
    • js 로직을 사용할 수 있다.
    • 그러므로 활용도가 높다!

그럼 HTML과의 차이는 무엇일까?

⇒ HTML은 마크업을 위한 언어이고 JSX는 JS 코드의 일부이므로

문법이 다르다.

형제 노드 사용 불가

function App() {
  return (
    <h1>Hello</h1>
    <p>Like lion</p>
  )
}

<div> 와 같은 태그로 감싸도 되나 의미없는 태그를 사용하지 않는 것이 좋다. <div> 보다 <Fragment><> 를 사용하면 된다!

camelCase 문법

ex) className, onClick, onChange → 요런 형태를 camelCase라고 하고 JSX에서는 이렇게 작성해주어야 한다!

JS 로직 - { }

function App(){
	const name = "Kevin";
	const friends = ["David", "Lilly"];

	return(
		<>
			<h1>{name}</h1>
		  {friends.map((friend, i) => (
				<p key={i}>{friend}</p>
			))
		</>
	);
}

위의 코드를 실행하면


Kevin

David Lilly


👆 이런식으로 웹 브라우저에 표시될 것이다!

⇒ 자바스크립트 표현식을 사용하기 위해서는 { } 안에 넣어서 사용해야 한다.

조건식

function App(){
	const name = "소연";
	return <>
		{name === "소연" ? <h1>나는 {name}</h1> : <h1>나는 {name}이 아니야</h1>}
	</>
}

Class Component

클래스 컴포넌트란 리액트에서 제공하는 React.Component 클래스를 상속하는 컴포넌트이다.

UI는 render()함수 내에 JSX 코드를 작성해 표기한다.

class React extends React.Comonent{
	render(){
		return <h1>Hello, {this.props.name}</h1>;
	}
}

클래스 컴포넌트의 경우 클래스의 멤버 변수를 직접적으로 수정하지 않는 한 한 번 만들어지면 계속 그 값이 유지된다.

그래서 render함수가 아무리 많이 호출되도 사용자에게 보여지는 데이터는 일정하다. 부모 컴포넌트에서 전달받는 props 가 변경되는 경우가 있어도 컴포넌트의 자체 this.state 는 변하지 않는다. 따라서 this.state 에 들어 있는 데이터는 변하지 않기 때문에 컴포넌트에서 가지고 있던 데이터를 잃어버리지 않고 사용자에게 일정한 데이터가 보여지는 것이다 !!

  • 만약 데이터를 변경해 UI에 업데이트 해주고 싶다면? **this.state만 업데이트** 해주면 리액트가 자동으로 render함수를 호출하고 브라우저에 업데이트 해준다!!

정리

  • React.Component 클래스를 상속한다.
  • 데이터는 this.state에 담아두어야 한다.
  • **render 함수에서 JSX문법**을 사용해 데이터를 어떻게 UI로 표기할 지 정의한다.
  • 리액트의 변경사항은 한 가지 방향으로 흘러간다. **데이터가 변경 -> UI 업데이트**

Function Component

리액트에서 컴포넌트를 만들 수 있는 두 번째 방법은 JSX를 리턴하는 함수를 정의하는 것이다!

function React(props){
	return <h1>Hello, {props.name}</h1>;
}
  • 함수형 컴포넌트를 만드는 경우
    • 컴포넌트 자체에 데이터(=state)가 없는 경우
    • 외부에서 전달받은 데이터(=props)만 보여주면 되는 경우
    • State, Props 둘 다 없는 정적인 컴포넌트인 경우

Class Component 와의 Function Component의 차이점

⇒ 함수형 컴포넌트는 함수 특성상 함수를 호출할 때마다 함수의 코드 블럭이 다시 실행되고 그 안에 선언된 모든 변수들은 함수가 실행되면서 재정의되고 값이 할당된다. 이처럼 함수가 호출될 때마다 모든 로컬 변수들의 값이 초기화되기 때문에 state를 보관해서 클래스 컴포넌트처럼 일관적으로 사용자에게 보여줄 수 없고 자체적인 데이터(=state)를 가질 수 없다.

원래 state와 life cycle 메서드들은 클래스 컴포넌트에서만 사용할 수 있었지만 React Hook이 도입되면서 함수형 컴포넌트에서도 클래스 컴포넌트의 대부분의 기능들을 사용할 수 있게 되었다!

둘 중에 뭐가 더 좋은가!

→ 요즘 트렌드는 함수형 + Hooks

 But 클래스형도 알고는 있자!

State

: 컴포넌트 내부에서 변경 가능한 값, 데이터

Ex1) 영어일 땐 한국어로, 영어가 아닐 땐 다시 영어로 바꾸는 예제

class Message extends Component {
  state = {
    message: "Hello",
  };

  handleClick = () => {
    const newMessage = this.state.message === "Hello" ? "안녕" : "Hello";
    this.setState({ message: newMessage });
  };
  render() {
    return (
      <>
        <h1>{this.state.message}</h1>
        <button onClick={this.handleClick}>언어 바꾸기</button>
      </>
    );
  }
}

Ex2) 카운터

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber(prevNumber => prevNumber + 1);
  }

  const onDecrease = () => {
    setNumber(prevNumber => prevNumber - 1);
  }

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

※ useState 안에 들어가는 값은 해당 state의 초기값이다.

리액트에 업데이트가 필요할 경우에는 setState함수를 호출해야 한다!!

그 후에 이제 리액트가 UI를 업데이트 하기 위해서 render 함수를 호출하는 것이다.

state를 업데이트할 때 이전 state 값에서 무언가가 계산이 되는 경우라면

setState(prevState => newState) 이렇게 화살표 함수를 사용해 이전 state 값을 받아 그걸로 업데이트 되는 값을 만들도록 함수를 호출하는 것이 더 좋다..!!!

  • 이유
    • setState()는 비동기적으로 작동한다.
    → state를 직접 수정하면서 여러 번 상태를 업데이트 하는 경우 이전 업데이트 내용이 다음 업데이트 내용으로 덮어 쓰여질 수 있고 예상치 못한 버그가 발생할 위험이 있다
    
- `PureComponent`에서 작동 X

Props

: Properties, 즉 컴포넌트의 속성을 설정할 때 사용하는 요소

부모 컴포넌트에서 자식 컴포넌트에게 요소를 전달하는 것!

defaultProps

: props값이 따로 지정되지 않았을 경우의 default 값을 설정해 주는 것이다.

props와 default 둘 다 설정이 안되면 아무것도 나타나지 않는다.

const Person = ({name, age}) => {
	return(
		<div>
			<h1>Name: {name}</h1>
			<h1>Age: {age}</h1>
		</div>
	);
};

Person.defaultProps = {
	name: "소연",
};

위의 코드는 name은 default가 정해져 있지만 age는 default가 정해져 있지 않다.

이를 브라우저에서 확인해보면

Name: 소연

Age:

👆 위처럼 name은 default값이 나타나지만 age는 아무것도 나타나지 않을 것이다!

children

: 컴포넌트 태그 사이의 내용을 보여주는 props

// App.js
const App(){
	return(
		<Person>요 안에 들어가는 내용이 props의 children</Person>
	);
};

// Person.js
const Person = (props) => {
	return <h1>{props.children}</h1>;
};

propTypes

: 타입을 지정해 검증할 때 사용한다.

import PropTypes from 'prop-types'

import PropTypes from "prop-types";

const Person = ({ name, age }) => {
  return (
    <div>
      <h1>Name: {name}</h1>
      <h1>Age: {age}</h1>
    </div>
  );
};

Person.propTypes = {
  name: PropTypes.string,
  age: PropTypes.number,
};

위의 코드에서 name의 타입은 string으로 지정해주고 age의 타입은 number로 지정해주었다!

profile
Github_qkrthdus605

0개의 댓글