티스토리 뷰

👏 컴포넌트 분리하기

 컴포넌트 분리하기에 앞서 Vue는 Vue의 Template문법 + HTML, React는 JSX 문법으로 UI를 작성하게 됩니다.

해당 예제는
Vue : https://github.com/baegofda/blog-vue
React: https://github.com/baegofda/blog-react 
위의 주소에서 데모와 함께 소스코드 확인이 가능합니다!

1. 상태 관리(state)

 상태 관리를 위한 state를 선언하겠습니다.

React에서는 React Hooks에서 제공하는 useRef, useState를 이용하여 state들을 관리합니다.

React

인풋의 값을 참조하기 위해 useRef()를 이용하여 Input에 ref={inputRef}를 선언합니다.

또 인풋 값을 바인딩하기 위한 inputText와 투두 리스트들을 담기 위한 items를 useState를 선언합니다.

import React, { useRef, useState } from "react";
import styled from "styled-components";
import Button from "../components/Button";
import ToDoItem from "../components/ToDoItem";

const ToDos = () => {
  const inputRef = useRef();
  const [inputText, setInputText] = useState("");
  const [items, setItems] = useState([]);
  
  //functions
  
  return (
    <Wrapper>
      <Title>TODO</Title>
      <Form>
        <Input
          ref={inputRef}
          value={inputText}
          type="text"
          onChange={onChange}
          placeholder="추가할 리스트를 입력하여 주세요 !"
        />
        <Button type="submit" name="추가하기" onClick={onClick} />
      </Form>
      <ul>
        {items.map((item) => (
          <ToDoItem
            key={item.id}
            item={item}
            onComplete={onComplete}
            onDelete={onDelete}
          />
        ))}
      </ul>
    </Wrapper>
  );
};

  // stlyes

export default ToDos;

Vue

 Vue에서는 data() 내에 사용할 state들의 초기값들을 선언합니다.

Vue의 ref는 선언해줄 필요 없이 $refs로 바로 접근이 가능하기 때문에 Input에 ref="todoInput"으로만 선언합니다.

<template>
  <main class="wrapper">
    <h1 class="title">TODO</h1>
    <form class="form">
      <input
        ref="todoInput"
        type="text"
        class="form__input"
        placeholder="추가할 리스트를 입력하여 주세요 !"
        v-model="inputText"
      />
      <Button type="submit" name="추가하기" @click="onClick" />
    </form>
    <ul>
      <ToDoItem
        v-for="todo in todos"
        :key="todo.id"
        :todo="todo"
        @onComplete="onComplete"
        @onDelete="onDelete"
      />
    </ul>
  </main>
</template>
<script>
import Button from "../components/Button.vue";
import ToDoItem from "../components/ToDoItem.vue";

export default {
  name: "Todos",
  data() {
    return {
      inputText: "",
      todos: [],
    };
  },
  methods: {
    //methods
  },
  components: {
    //components
  },
};
</script>

<style scoped>
  //styles
</style>

2. 함수 선언

React와 Vue 모두 Javascript 기반이기 때문에 함수 내에서 사용하는 문법은 큰 틀에서는 Javascript 문법으로 동일합니다.

React

 React에서는 선언한 state에 값을 업데이트하기 위해서는 setState을 이용합니다.

import React, { useRef, useState } from "react";
import styled from "styled-components";
import Button from "../components/Button";
import ToDoItem from "../components/ToDoItem";

const ToDos = () => {
  const inputRef = useRef();
  const [inputText, setInputText] = useState("");
  const [items, setItems] = useState([]);

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

  const onClick = (e) => {
    e.preventDefault();
    setItems((items) => {
      const item = {
        id: Date.now(),
        content: inputRef.current.value,
        isCompleted: false,
      };
      const newItems = [...items, item];
      return newItems;
    });
    setInputText("");
    inputRef.current.focus();
  };

  const onComplete = (id) => {
    setItems((items) =>
      items.map((item) => {
        if (item.id === id) {
          return { ...item, isCompleted: !item.isCompleted };
        }
        return item;
      })
    );
  };

  const onDelete = (id) => {
    setItems((items) => items.filter((item) => item.id !== id));
  };

  return (
    <Wrapper>
      <Title>TODO</Title>
      <Form>
        <Input
          ref={inputRef}
          value={inputText}
          type="text"
          onChange={onChange}
          placeholder="추가할 리스트를 입력하여 주세요 !"
        />
        <Button type="submit" name="추가하기" onClick={onClick} />
      </Form>
      <ul>
        {items.map((item) => (
          <ToDoItem
            key={item.id}
            item={item}
            onComplete={onComplete}
            onDelete={onDelete}
          />
        ))}
      </ul>
    </Wrapper>
  );
};

//styles

export default ToDos;

Vue

 Vue에서는 사용할 function은 methods에 작성하며 this로 내부 state, function, ref 등에 접근하여 값을 업데이트합니다.

또 React에서는 onChange를 이용하여 inputText를 업데이트하고 value로 바인딩을 하여 사용하지만

vue에서는  v-model을 이용하여 inputText를 사용하게되면 업데이트와 함께 데이터 바인딩이 가능합니다.

<template>
  <main class="wrapper">
    <h1 class="title">TODO</h1>
    <form class="form">
      <input
        ref="todoInput"
        type="text"
        class="form__input"
        placeholder="추가할 리스트를 입력하여 주세요 !"
        v-model="inputText"
      />
      <Button type="submit" name="추가하기" @click="onClick" />
    </form>
    <ul>
      <ToDoItem
        v-for="todo in todos"
        :key="todo.id"
        :todo="todo"
        @onComplete="onComplete"
        @onDelete="onDelete"
      />
    </ul>
  </main>
</template>
<script>
import Button from "../components/Button.vue";
import ToDoItem from "../components/ToDoItem.vue";

export default {
  name: "Todos",
  data() {
    return {
      inputText: "",
      todos: [],
    };
  },
  methods: {
    onClick(e) {
      e.preventDefault();
      const todo = {
        id: Date.now(),
        content: this.inputText,
        isCompleted: false,
      };
      this.todos = [...this.todos, todo];
      this.inputText = "";
      this.$refs.todoInput.focus();
    },
    onComplete(id) {
      this.todos = this.todos.map((todo) => {
        if (todo.id === id) {
          return { ...todo, isCompleted: !todo.isCompleted };
        }
        return todo;
      });
    },
    onDelete(id) {
      this.todos = this.todos.filter((todo) => todo.id !== id);
    },
  },
  components: {
    //components
  },
};
</script>

<style scoped>
  //style
</style>
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함