Vue.jsエンジニアのReact入門 - コンポーネントの親子関係
Vue.js エンジニアの React 入門。
React の実装方法を Vue.js と対比しながら理解を深めていくシリーズ。
今回は、「コンポーネントの親子関係」である。
親子間でのデータのやり取り、イベントハンドリングを確認する。
Vue.js
まずは、Vue.js での実装方法から確認する。
親要素から子要素へのデータ受け渡しは、プロパティ props
で行う。子要素から親要素へのイベント通知は、 $emit
メソッドを用いる。また、上図には記載していないが、親要素から子要素のメソッドを実行したい場合は、 ref
を用いることで、子要素にアクセスすることができる。
<template> <div class="parent"> <Child ref="child" color="red" :user="user" @submit="parentFunction" /> </div> </template> <script> import Child from 'src/components/child' export default { data: () => ({ user: { name: '太郎', age: 20 } }), methods: { parentFunction(data) { // method }, reset() { this.$refs.child.childFunction() } } } </script>
<template> <div class="child"> <form> <input v-model="text"> <button @click="$emit('submit', text)">send</button> </form> </div> </template> <script> export default { props: { color: { type: String, default: 'white' } user: { type: Object, default: () => ({}) } }, data: () => ({ text: '' }), methods: { childFunction(data) { // method } } } </script>
React
Reactの場合は、データやイベントを区別することなく、プロパティを指定することで同様のことが実現できる。子要素では、 props
を用いてそれぞれのプロパティにアクセスできる。
import React from 'react' import Child from './components/Child' const App = () => { const user = { name: '太郎', age: 20 }, const parentFunction = (data) => { //method }, return ( <Child color="red" user={user} onSubmit={parentFunction} /> ) } export default App
import React from 'react' const Child = (props) => { // props.color // props.user // props.onSubmit(data) } export default Child
Vue.js 同様に、プロパティのバリデーションなどを行いたい場合は、 prop-types ライブラリを用いる。
また、Vue.js には、レイアウトのテンプレート機能を実現できる slot
という便利なメソッドがあった。
Vue.js
name のない slot
要素は、暗黙的に「default」という名前を持つ。名前付きスロットにコンテンツを指定するには、<template>
に対して v-slot ディレクティブを使って、スロット名を引数として与える。defaultの場合は、<template>
を使って明示しなくても問題ない。
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <template v-slot:default> <p>A paragraph for the main content.</p> <p>And another one.</p> </template> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
React
Reactの場合は、プロパティの children
を用いて、要素の受け渡しを行うことができる。ただし、上記のような名前指定をしての挿入をする場合は、以下のように独自のプロパティで React コンポーネントを受け渡しすることで実現できる。
const BaseLayout = (props) => { return ( <div className="wrapper"> <header>{props.header}</header> <main>{props.content}</main> <footer>{props.footer}</footer> </div> ) } export default BaseLayout
import React from 'react' import BaseLayout from './components/baseLayout.jsx' import Header from './components/header.jsx' import Content from './components/content.jsx' import Footer from './components/footer.jsx' const App = (BaseLayout) => { return ( <BaseLayout header={<Header />} content={<Content />} footer={<Footer />} /> ) } export default App
まとめ
コンポーネントの親子関係についてまとめを行った。Vue.js は様々なメソッドがあるのに対して、React の場合はシンプルな構成になっていると思えた。
それでは、ステキな開発ライフを。