Vue와 React의 데이터 흐름 차이

박희주·2022년 10월 28일
0

Vue와 React의 데이터 흐름 차이 간단 리뷰


1. Data를 props로 전달하기

1-1. React

import { useState } from 'react';
import Counter from './Counter.js'; // Vue와 차이점 중 하나로 컴포넌트릉 import할 때는 상위에 명시해주고 활용하면 끝!

const Parent = () => {
	const [value, setValue] = useState(0);

	return (
		<div>
			<Counter value={value} />
		</div>
	)
}

export default Parent;
  • 부모 컴포넌트에서 보유한 데이터를 자식 컴포넌트에게 넘겨줄때는 props라는 개념이 있다.
    • props는 기본적으로 단방향 데이터 전달방식이다.
    • props를 전달 할때는 자식 컴포넌트에게 props이름={전달할데이터}로 명시해준다.

1-2. Vue

<!-- 부모 컴포넌트 -->
<template>
  <!-- props의 이름은 자유롭게 작명이 가능 -->
  <Counter :value="value" />
  <!-- 혹은 -->
  <Counter v-bind:value="value" />
</temlplate>

<script>
import Counter from './Counter.vue';

export default {
  name: "Parent",
  components: { Counter }, // React와의 차이점에서 컴포넌트를 import하고 components라는 객체에 등록을 해야 활용 가능하다.
  data() {
  	return{
      value: 0,
    }
  }
}
</script>
  • React와의 차이로 Vue에서는 데이터를 props로 전달할 때 v-bind혹은 :의 키워드를 활용해서 전달하고 자식컴포넌트에서는 props객체를 통해 부모로 부터 받아오는 데이터를 등록하고 전달 받는다.

2. 부모에서 전달한 props를 자식이 렌더링 하는 법

2-1. React

  • React에서는 전달 받은 props를 렌더링 하기 위해서는 { }를 활용하여 렌더링 한다.

    const Counter = (props) => {
      return (
        <div>{ props.value }</div>
      )
    }
    
    // 혹은 구조 분해 할당으로도 표현할 수 있다.
    const Counter = ({ value }) => {
      return (
        <div>{ value }</div>
      )
    }
    
    export default Counter;

2-2. Vue

  • Vue에서는 전달 받은 props를 렌더링 하기 위해서는 {{ }}를 활용하여 렌더링 한다.

    • Vue에서는{{ }}를 콧수염 구문(Mustache Syntax)이라고 칭한다.
    <!-- 자식컴포넌트 -->
    <template>
      <div>{{ value }}</div>
    </template>
    
    <script>
    export default {
      name: "Counter",
      props: ['value'], // 배열로 등록할 때는 props의 이름만 적어주면 된다.
      props: {
        value: Number, // 객체로 등록할 때는 props의 이름과 타입을 명시해줘야 한다. => { props이름 : 타입 }
      }
    }
    </script>

3. props로 전달한 이벤트 실행 방법의 차이

위의 내용들을 토대로 가장 기초적인 Counter 기능을 만들어 보자

3-1. React

import { useState } from 'react';

// 부모 컴포넌트
const Parent = () => {
  // 넘겨줄 데이터 선언
  const [value, setValue] = useState(0);

  // value를 증가시킬 함수 생성
  const increase = () => {
    setValue(prev => prev + 1)
  }
  // value를 감소시킬 함수 생성
  const decrease = () => {
    setValue(prev => prev - 1)
  }

  return (
    {/* value라는 데이터와 이 데이터를 증감 시킬 increase, decrease함수를 props로 전달 */}
    <Counter value={value} onIncrease={increase} onDecrease={decrease} />
  )
}

// 자식 컴포넌트
const Counter = ({ value, onIncrease, onDecrease }) => {
  return (
    {/* props로 받은 value를 렌더링 */}
    <div>{ value }</div>
    {/* 버튼에 onClick이벤트를 부여해 props로 받는 함수를 직접 실행 */}
    <button onClick={onDecrease}>-1</button>
    {/* 버튼에 onClick이벤트를 부여해 props로 받는 함수를 직접 실행 */}
    <button onClick={onIncrease}>+1</button>
  )
}

export default Counter;

3-2. Vue

<!-- 부모컴포넌트 -->
<template>
  <div>
  <Counter :value="value" @onIncrease="increase" @onDecrease="decrease" />
  </div>
</template>

<script>
import Counter from './Counter.vue';

export default {
  name: 'ParentVue',
  components: { Counter },
  data() {
    return {
      value: 0,
    };
  },
  methods: {
    increase() {
      this.value + 1; // Vue에서는 data(state)에 접근할 때는 this를 활용한다. 그래서 화살표함수는 사용할 수 없다.
    },
    decrease() {
      this.value - 1;
    },
  },
}
</script>

<!-- 자식컴포넌트 -->
<template>
  <div>
    <!-- 부모에게서 받은 props데이터를 렌더링 -->
    <div>{{ value }}</div>
    <!-- 감소 함수를 직접 실행시키는 것이 아닌 부모 컴포넌트의 decrease함수를 실행시키는 요청을 진행 -->
    <button @click="onDecrease">-1</button>
    <!-- 증가 함수를 직접 실행시키는 것이 아닌 부모 컴포넌트의 increase함수를 실행시키는 요청을 진행 -->
    <button @click="onIncrease">+1</button>
  </div>
</template>

<script>
export default {
  name: 'CounterVue',
  props: {
    value: Number,
  },
  methods: {
    onIncrease() {
      this.$emit('onIncrease') // 이 $emit이 React와 Vue의 고유의 특징 차이라고 생각한다.
    },
    onDecrease() {
      this.$emit('onDecrease')
    },
  },
};
</script>

4. 정리

  • React에서는 데이터가 무조건 단방향 (부모 → 자식)으로 이동하고 함수나 기타 데이터들도 마찬가지이다.
  • Vue에서는 데이터가 양방향으로 바인딩해서 컨트롤이 가능한 점에 있어 React와 가장 큰 차이를 보인다고 생각한다.
    • React에서는 부모가 함수를 갖고 있을 때 해당 함수를 props로 내려주면 그 함수를 받아서 자식컴포넌트가 사용하는 형식으로 작동한다.
    • 하지만 Vue에서는 부모가 함수를 갖고 있을 때 자식컴포넌트에서 그 함수를 props로 받아서 사용하는 것이 아니고 자식컴포넌트에서 $emit을 통해 실행시키고자 하는 함수를 명시해 이벤트 요청을 발생시키면 부모컴포넌트에서 그 요청을 받아 해당 함수를 실행시키는 느낌으로 이해했다.
profile
하나부터 열까지, 머리부터 발 끝까지

0개의 댓글