React와 Vue에서 똑같은 앱을 만들었습니다. 차이점은 다음과 같습니다. [2019 년판]
본문
React vs Vue. 마지막으로 Vue와 React! ? [2019 년 업데이트 및 재 작성 : 이제 React Hooks 포함]
직장에서 Vue를 사용하면서 나는 그것에 대해 상당히 확실하게 이해했습니다. 그러나 나는 울타리 반대편의 잔디가 어떤지 알고 싶어했다. 이 시나리오의 잔디는 React이다.
나는 React 문서를 읽고 몇 가지 튜토리얼 비디오를 보았고 훌륭했지만 모두 알고 싶었던 것은 React가 Vue와 어떻게 다른지였습니다. “다른”이라는 용어는 둘 다 가상 DOMS를 가지고 있는지 또는 페이지를 렌더링 하는 방법과 같은 것을 의미하지 않았습니다. 누군가 코드를 설명 할 시간을 갖기를 원했습니다! Vue 나 React (또는 웹 개발 전체)를 처음 접하는 사람이 이 둘의 차이점을 더 잘 이해할 수 있도록 이것을 설명하는 데 시간이 걸리는 기사를 찾고 싶었습니다.
불행히도, 나는 이것을 해결하는 것을 찾을 수 없었습니다. 그래서 나는 유사점과 차이점을 보기 위해 직접 만들어야 한다는 것을 깨달았습니다. 그렇게 할 때, 나는 전체 프로세스를 문서화하여 이것에 관한 기사가 마침내 존재할 것이라고 생각했습니다.
사용자가 목록에서 항목을 추가하고 삭제할 수 있도록 상당히 표준적인 To Do App을 작성하려고 시도했습니다. 두 앱 모두 기본 CLI (React 용 create-react-app 및 Vue 용 vue-cli)를 사용하여 구축되었습니다. CLI는 Command Line Interface의 약어입니다. ?
어쨌든,이 소개는 이미 예상보다 깁니다. 이제 두 앱의 모양을 간단히 살펴 보겠습니다.
두 앱의 CSS 코드는 정확히 동일하지만 위치에 차이가 있습니다. 이를 염두에 두고 다음으로 두 앱의 파일 구조를 살펴 보겠습니다.
구조가 거의 동일하다는 것을 알 수 있습니다. 여기서 유일한 차이점은 React 앱에 두 개의 CSS 파일이 있고 Vue 앱에는 없는 파일입니다. 그 이유는 create-react-app에서 React 구성 요소에 스타일을 유지하기 위해 첨부 파일이 있는 반면 Vue CLI는 스타일이 실제 구성 요소 파일 내에 선언되는 포괄적 인 접근 방식을 채택하기 때문입니다.
업데이트 : 뒤늦게 React가 3 개의 CSS 파일을 가지고 있는 것이 더 합리적이었으므로 App.js, ToDo.js 및 ToDoItem.js에 대한 별도의 CSS 파일이 있었습니다.
궁극적으로 둘 다 동일한 것을 달성하며 React 또는 Vue에서 CSS를 다르게 구성 할 수는 없습니다. 그것은 실제로 개인 취향에 달려 있습니다. 스타일 구성 요소 및 감정과 같은 여러 CSS-in-JS 솔루션이 있기 때문에 특히 React와 관련하여 CSS가 어떻게 구성 되어야 하는 지에 대해 개발자 커뮤니티로부터 많은 토론을 들을 것입니다. CSS-in-JS는 말 그대로 들립니다. 이것들은 유용하지만 지금은 두 CLI에 배치 된 구조를 따릅니다.
그러나 더 나아 가기 전에 일반적인 Vue 및 React 구성 요소가 어떻게 보이는지 살펴 보겠습니다.
이제 그 길을 벗어났습니다. 딱딱한 세부 사항을 살펴 봅시다!
데이터를 어떻게 변경합니까?
그러나 먼저 "데이터 변경"이라는 의미는 무엇입니까? 좀 기술적으로 들리지 않습니까?
기본적으로 우리가 저장 한 데이터를 변경하는 것을 의미합니다. 따라서 사람 이름의 값을 John에서 Mark로 변경하려면 '데이터를 변경' 해야 합니다. 이것이 바로 React와 Vue의 주요 차이점입니다. Vue는 기본적으로 데이터를 자유롭게 업데이트 할 수 있는 데이터 객체를 생성하지만 React는 상태 후크라고 하는 것을 통해 이를 처리합니다.
아래 이미지에서 두 가지 설정을 살펴보면 다음에 어떤 일이 발생하는지 설명하겠습니다.
따라서 동일한 데이터를 둘 다에 전달했음을 알 수 있지만 구조는 약간 다릅니다.
Vue에서는 일반적으로 데이터가 있는 객체를 반환하는 data () 함수 안에 구성 요소에 대한 모든 변경 가능한 데이터를 배치합니다 (오른쪽 이미지에서 볼 수 있듯이).
React를 사용하거나 최소한 2019 년부터는 일반적으로 일련의 후크를 통해 상태를 처리합니다. 이전에 이런 유형의 개념을 보지 못했다면 처음에는 조금 이상하게 보일 수 있습니다. 기본적으로 다음과 같이 작동합니다.
할 일 목록을 만들고 싶다고 가정 해 봅시다. list라는 변수를 만들어야 할 수도 있고 문자열이나 객체의 배열을 취해야 할 수도 있습니다 (각 todo 문자열에 ID와 다른 것들을 부여하려는 경우 const [ list, setList] = useState ([]) 여기서는 React가 후크 (useState)라고 부르는 것을 사용하고 있으며, 기본적으로 컴포넌트 내에서 로컬 상태를 유지할 수 있습니다.
또한 useState() 내부에 빈 배열[]을 전달한 것을 알 수 있습니다. 우리가 거기에 넣은 것은 목록을 처음에 설정하려는 것입니다.이 경우 빈 배열이 되고 싶습니다. 그러나 위의 이미지에서 배열 내부의 일부 데이터를 전달 했으므로 list의 초기화 데이터가 됩니다. setList의 기능이 궁금하십니까? 이것에 대해서는 나중에 더 있을 것입니다!
그렇다면 앱에서 변경 가능한 데이터를 어떻게 참조합니까?
‘Sunil’이라는 가치가 부여 된 name이라는 데이터가 있다고 가정 해 보겠습니다.
Vue에서 이것은 data() 객체 안에 있고 이름은 ‘Sunil’입니다. 앱에서 this.name을 호출하여 이를 참조합니다. this.name =‘John’을 호출하여 업데이트 할 수도 있습니다. 이것은 내 이름을 John으로 바꿀 것입니다. 존이라고 불렀을 때의 느낌이 확실하지 않지만, 호, 일이 일어납니다! ?
React에서 useState()로 만든 작은 상태 조각이 있으므로 const [name, setName] = useState('Sunil') 줄을 따라 무언가를 만들었을 가능성이 있습니다. 우리의 앱에서는 단순히 이름을 호출하여 동일한 데이터를 참조합니다. 여기서 중요한 차이점은 React는 이러한 종류의 쉽고 간결한 변이를 막기 위해 제한이 있기 때문에 단순히 name = 'John'을 쓸 수 없다는 것입니다. 따라서 React에서 setName('John')을 작성합니다. 여기에서 setName 비트가 작동합니다. 기본적으로 const [name, setName] = useState('Sunil')에서 두 개의 변수를 만듭니다. 하나는 const name = 'Sunil'이 되고 두 번째 const setName에는 이름을 새 값으로 다시 만들 수 있는 함수가 할당됩니다.
효과적으로 React와 Vue는 여기서 동일한 작업을 수행하여 업데이트 할 수 있는 데이터를 생성합니다. Vue는 기본적으로 데이터 조각이 업데이트 될 때마다 기본적으로 자체 버전의 name과 setName을 결합합니다. 간단히 말해 React는 상태를 업데이트하기 위해 내부 값으로 setName()을 호출해야 하므로 Vue는 데이터 객체 내부의 값을 업데이트하려고 할 때 이 작업을 원한다고 가정합니다. 그렇다면 React는 왜 함수에서 값을 분리하는 데 신경을 쓰며 useState()가 필요한가? 설명을 위해 이것을 Revanth Kumar에게 넘겨주십시오.
“React는 상태가 변경 될 때마다 특정 수명주기 후크를 다시 실행하기를 원하기 때문입니다. useState 함수를 호출하면 상태가 변경되었음을 알 수 있습니다. 상태를 직접 변경 한 경우 React는 변경 사항 및 실행 주기주기 등을 추적하기 위해 훨씬 더 많은 작업을 수행해야 합니다. 따라서 간단한 React를 사용하려면 useState를 사용하십시오. "
이제 변이가 발생 했으므로 To Do Apps 모두에 새 항목을 추가하는 방법을 살펴보면서 엉뚱하고 하자.
새로운 할 일 항목을 어떻게 만듭니까?
React:
const createNewToDoItem = () => {
const newId = Math.max.apply(null, list.map((t) => t.id)) + 1
const newToDo = { id: newId, text: toDo }; setList([...list, newToDo]);
setToDo("");
};
React는 어떻게 했습니까?
React에서 입력 필드에는 value라는 속성이 있습니다. 이 값은 onChange 이벤트 리스너를 통해 값이 변경 될 때마다 자동으로 업데이트 됩니다. JSX (기본적으로 HTML의 변형)는 다음과 같습니다.
<input type="text"
value={toDo}
onChange={handleInput}/>
따라서 값이 변경 될 때마다 상태가 업데이트 됩니다. handleInput 함수는 다음과 같습니다.
const handleInput = (e) => {
setToDo(e.target.value);
};
이제 사용자가 페이지에서 + 버튼을 눌러 새 항목을 추가 할 때마다 createNewToDoItem 함수가 트리거 됩니다. 이 기능을 다시 살펴보고 진행 중인 작업을 분석해 보겠습니다.
const createNewToDoItem = () => {
const newId = Math.max.apply(null, list.map((t) => t.id)) + 1
const newToDo = { id: newId, text: toDo }; setList([...list, newToDo]);
setToDo("");
};
본질적으로 newId 함수는 기본적으로 새 할 일 항목에 제공 할 새 ID를 작성합니다. newToDo 변수는 newId의 값이 주어진 id 키를 갖는 객체입니다. 또한 toDo의 값을 값으로 사용하는 텍스트 키가 있습니다. 입력 값이 변경 될 때마다 업데이트 되는 것과 동일한 작업 관리입니다.
그런 다음 setList 함수를 실행하고 전체 목록과 새로 작성된 newToDo를 포함하는 배열을 전달합니다.
... list, bit가 이상하게 보일 경우 처음 세 점은 스프레드 연산자로 알려진 것으로, 기본적으로 전체 배열을 전달하지 않고 목록의 모든 값을 별도의 항목으로 전달합니다. 배열로 항목. 혼란스러운가? 그렇다면 스프레드에 대해 읽어 보는 것이 좋습니다.
어쨌든 마지막으로 setToDo()를 실행하고 빈 문자열을 전달합니다. 입력 값이 비어 있어 새로운 할 일을 입력 할 수 있습니다.
Vue:
createNewToDoItem() {
const newId = Math.max.apply(null, this.list.map(t => t.id)) + 1;
this.list.push({ id: newId, text: this.todo });
this.todo = "";
}
Vue는 어떻게 했습니까?
Vue에서 입력 필드에는 v-model이라는 핸들이 있습니다. 이를 통해 양방향 바인딩으로 알려진 작업을 수행 할 수 있습니다. 입력 필드를 신속하게 살펴보고 진행 상황을 설명하겠습니다.
<input type="text" v-model="todo"/>
V-Model은이 필드의 입력을 toDoItem이라는 데이터 객체에 있는 키에 연결합니다. 페이지가 로드 되면 toDoItem은 빈 문자열로 설정해야 합니다. todo :‘’. 여기에 todo : '여기에 텍스트를 추가하십시오'와 같은 데이터가 이미 있는 경우 입력 필드에 이미 텍스트가 추가되어 입력 필드가 로드 됩니다. 어쨌든, 빈 문자열로 돌아가서 입력 필드에 입력 한 텍스트가 todo 값에 바인딩 됩니다. 이것은 효과적으로 양방향 바인딩입니다 (입력 필드는 데이터 개체를 업데이트 할 수 있고 데이터 개체는 입력 필드를 업데이트 할 수 있습니다).
이전의 createNewToDoItem() 코드 블록을 되돌아 보면 할 일의 내용을 목록 배열로 푸시 한 다음 할 일을 빈 문자열로 업데이트하는 것을 볼 수 있습니다.
또한 React 예제에서 사용 된 것과 동일한 newId() 함수를 사용했습니다.
목록에서 어떻게 삭제합니까?
React:
const deleteItem = (item) => {
setList(list.filter((todo) => todo !== item));
};
React는 어떻게 했습니까?
따라서 deleteItem() 함수가 ToDo.js 내에 있지만 먼저 ToToItem />의 소품으로 deleteItem() 함수를 소품으로 전달하여 ToDoItem.js 내에서 쉽게 참조 할 수 있었습니다.
<ToDoItem deleteItem={deleteItem}/>
이것은 먼저 자식이 접근 할 수 있도록 함수를 전달합니다. 그런 다음 ToDoItem 구성 요소 내에서 다음을 수행합니다.
<button className="ToDoItem-Delete" onClick={() => deleteItem(item)}> - </button>
부모 구성 요소 안에 있는 함수를 참조하기 위해 해야 할 일은 props.deleteItem을 참조하는 것입니다. 이제 코드 예제에서 props.deleteItem 대신 deleteItem을 작성했음을 알 수 있습니다. 이는 props 객체의 일부를 가져 와서 변수에 할당 할 수 있는 구조화라고 하는 기술을 사용했기 때문입니다. ToDoItem.js 파일에는 다음이 있습니다.
const ToDoItem = (props) => {
const { item, deleteItem } = props;
}
이는 props.item과 동일한 값이 할당 된 item이라는 변수와 props.deleteItem에서 값이 할당 된 deleteItem이라는 두 가지 변수를 생성했습니다. props.item과 props.deleteItem을 사용하여 이 모든 파괴적인 것을 피할 수 있었지만 언급 할 가치가 있다고 생각했습니다!
Vue:
onDeleteItem(item){
this.list = this.list.filter(todo => todo !== item);
}
Vue는 어떻게 했습니까?
Vue에서는 약간 다른 접근 방식이 필요합니다. 우리는 본질적으로 여기에서 세 가지 일을 해야 합니다 :
먼저 요소에서 함수를 호출하려고 합니다.
<div class=”ToDoItem-Delete” @click=”deleteItem(item)”>-</div>
그런 다음 자식 구성 요소 (이 경우 ToDoItem.vue) 내에 메서드로 emit 함수를 만들어야 합니다.
deleteItem(item) {
this.$emit('delete', item)
}
이와 함께 ToDo.vue 내에 ToDoItem.vue를 추가하면 실제로 함수를 참조한다는 것을 알 수 있습니다.
<ToDoItem v-for="todo in list"
:todo="todo"
@delete="onDeleteItem" // <-- this :)
:key="todo.id" />
이것이 바로 사용자 정의 이벤트 리스너입니다. '삭제'문자열로 이미 터가 트리거 되는 경우를 수신합니다. 이것이 들리면 onDeleteItem이라는 함수를 트리거 합니다. 이 함수는 ToDoItem.vue가 아닌 ToDo.vue 내부에 있습니다. 앞에서 설명한 것처럼 이 함수는 단순히 클릭 한 항목을 제거하기 위해 데이터 객체 내부의 할일 배열을 필터링 합니다.
Vue 예제에서 @click 리스너 내부에 $emit 부분을 다음과 같이 간단하게 작성할 수 있다는 점도 주목할 가치가 있습니다.
<div class=”ToDoItem-Delete” @click=”$emit(‘delete’, item)”>-</div>
이것은 단계 수를 3에서 2로 줄였을 것이며, 이것은 단순히 개인 취향에 달려 있습니다.
요컨대, React의 하위 구성 요소는 소품을 통해 부모 기능에 액세스 할 수 있습니다 (소품을 아래로 전달하면 상당히 표준적인 관행이며 다른 React 예제에서 이 많은 시간을 보게 됩니다) .Vue에서는 일반적으로 부모 구성 요소 내에서 수집되는 자식에서 이벤트를 생성합니다.
이벤트 리스너를 어떻게 전달합니까?
React:
클릭 이벤트와 같은 간단한 작업을 위한 이벤트 리스너는 간단합니다. 다음은 새 ToDo 항목을 작성하는 단추에 대한 클릭 이벤트를 작성하는 방법의 예입니다.
<button className=”ToDo-Add” onClick={createNewToDoItem}>+</div>.
여기에서 매우 쉬우며 바닐라 JS로 인라인 onClick을 처리하는 방법과 거의 같습니다. Vue 섹션에서 언급 했듯이 enter 버튼을 누를 때마다 처리 할 이벤트 리스너를 설정하는 데 시간이 조금 더 걸렸습니다. 이를 위해서는 입력 태그가 onKeyPress 이벤트를 처리해야 합니다.
<input type=”text” onKeyPress={handleKeyPress}/>.
이 함수는 다음과 같이 'enter'키를 눌렀을 때마다 createNewToDoItem 함수를 트리거 했습니다.
handleKeyPress = (e) => {
if (e.key === ‘Enter’) {
createNewToDoItem();
}
};
Vue:
Vue에서는 매우 간단합니다. @ 기호를 사용하고 원하는 이벤트 리스너 유형을 사용합니다. 예를 들어 클릭 이벤트 리스너를 추가하기 위해 다음을 작성할 수 있습니다.
<button class=”ToDo-Add” @click=”createNewToDoItem()”>+</div>
참고 : @click은 실제로 v-on : click을 작성하기 위한 축약 형입니다. Vue 이벤트 리스너의 멋진 점은 이벤트 리스너가 두 번 이상 트리거 되는 것을 막는 .once와 같이 묶을 수 있는 것들이 많이 있다는 것입니다. 키 스트로크를 처리하기 위해 특정 이벤트 리스너를 작성하는데도 많은 단축키가 있습니다. Enter 버튼을 누를 때마다 새 ToDo 항목을 작성하는 데 React에서 이벤트 리스너를 작성하는 데 시간이 조금 더 걸린다는 것을 알았습니다. Vue에서는 다음과 같이 간단하게 작성할 수 있었습니다.
<input type=”text” v-on:keyup.enter=”createNewToDoItem”/>
자식 구성 요소에 데이터를 어떻게 전달합니까?
React:
이에 React하여 props이 생성 된 지점에서 자식 구성 요소에 소품을 전달합니다.
<ToDoItem key={key.id} item={todo} />
여기 두 개의 소품이 ToDoItem 컴포넌트에 전달 된 것을 볼 수 있습니다. 이제부터 this.props를 통해 자식 구성 요소에서 참조 할 수 있습니다. item.todo prop에 접근하기 위해 우리는 단순히 props.item을 호출합니다.
Vue:
Vue에서는 소품이 생성되는 지점에서 자식 구성 요소에 소품을 전달합니다.
<ToDoItem v-for="item in list"
:item="item"
@delete="onDeleteItem"
:key="item.id" />
이 작업이 완료되면 props : [‘todo’]와 같이 하위 구성 요소의 props 배열로 전달합니다. 그런 다음 아이의 이름으로 참조 할 수 있습니다. 따라서 우리의 경우에는 ‘할 일’입니다.
부모 컴포넌트로 데이터를 다시 내보내는 방법은 무엇입니까?
React:
먼저 하위 구성 요소를 호출하는 위치에서 소품으로 참조하여 하위 구성 요소에 함수를 전달합니다. 그런 다음 props.whateverTheFunctionIsCalled를 참조하거나 onDestructuring을 사용하는 경우 whateverFunctionIsCalled를 참조하여 onClick과 같은 모든 방법으로 자식에 대한 함수 호출을 추가합니다. 그러면 상위 컴포넌트에 있는 기능이 트리거됩니다. ‘목록에서 삭제하는 방법’ 섹션에서 이 전체 프로세스의 예를 볼 수 있습니다.
Vue:
우리의 자식 컴포넌트에서, 우리는 단순히 부모 함수로 값을 내보내는 함수를 작성합니다. 부모 컴포넌트에서, 우리는 그 값이 방출 될 때 수신하는 함수를 작성하여 함수 호출을 트리거 할 수 있습니다. ‘목록에서 삭제하는 방법’섹션에서 이 전체 프로세스의 예를 볼 수 있습니다.
그리고 우리는 그것을 가지고 있습니다! ?
데이터를 추가, 제거 및 변경하고 소품 형식의 데이터를 부모에서 자식으로 전달하고 이벤트 리스너 형식으로 자식에서 부모로 데이터를 보내는 방법을 살펴 보았습니다. 물론 React와 Vue 사이에는 다른 많은 차이점과 단점이 있지만 이 기사의 내용이 두 프레임 워크가 물건을 어떻게 처리하는지 이해하기 위한 약간의 기초로 도움이 되기를 바랍니다. 이 글을 읽는 것을 즐겼다면 박수를 남기면서 사랑을 보여주십시오 – 힌트, 최대 50 개까지 남겨 둘 수 있습니다!
이 기사에 사용 된 스타일을 포크 하는 데 관심이 있고 자신 만의 스타일을 만들고 싶다면 자유롭게 하시기 바랍니다. ?
Github은 두 앱 모두에 링크합니다 :
Vue ToDo : https://github.com/sunil-sandhu/vue-todo-2019
React ToDo: https://github.com/sunil-sandhu/react-todo-2019
이 기사의 2018 버전
- 이전글Inertia.js - The Modern Monolith - 소개 19.10.10
- 다음글Svelte 템플릿에 주석을 추가하는 방법 19.10.10