ãã®èšäºãèªãã§æãåããã°ãç°å¢æ§ç¯ãªã©ã®æ¬è³ªçã§ãªãããšã«ã€ãŸãããã«ãReact/JSXã®åºæ¬çãªæžãæ¹ã身ã«ã€ããããŸãã
ãªããªãã
- poiãšããç°å¢èšå®äžèŠã®ãã«ãããŒã«ã䜿ã1
- ã³ããããã°åãå®å šãªãµã³ãã«ã³ãŒããçšæããŠãã
- åäœæã®ã¹ã¯ã·ã§ã貌ã£ãŠããã®ã§ãåçµããããã°ã©ã ãæ£ããã®ãããã
ããã§ãã
身ã«ã€ããããã«ã¯èªåã®æã§åããããšã倧äºãªã®ã§ãåçµããªãããèªåãªãã«æ¹é ãªã©ãã€ã€éãã§ã¿ãŠãã ãããæ³å®æçšæéã¯ã2ã3æéçšåºŠã§ãã
ãªããã¿ãªããã¯ããã§ã«äœããã®çç±ã§Reactã䜿ããããšããåæ©ããããšæ³å®ããŠãããããReactã®é åã«ã€ããŠã¯èªããŸããã
ç°å¢èšå®
Node.jsã®ããŠã³ããŒããšã€ã³ã¹ããŒã«ãå¿
èŠã§ãã
ãã¡ã ããããŠã³ããŒãããŠãã ããã
Node.jsãã€ã³ã¹ããŒã«ã§ãããããããžã§ã¯ããäœæããŸãã
# ãã£ã¬ã¯ããªäœæ
mkdir react-training
# äœæãããã£ã¬ã¯ããªã«ç§»å
cd react-training
# ãããžã§ã¯ãã®åæå
npm init --yes
# ãããžã§ã¯ãã«äŸåã©ã€ãã©ãªã远å
npm install --save poi react react-dom
以äžã§æºåã¯å®äºã§ããããšã¯ããã¡ã€ã«ã«JavaScriptã®ã³ãŒããæžããŠã
npx poi --jsx react index.jsx
ãå®è¡ããã°ããã¡ã€ã«ã®ã³ã³ãã€ã«ãã§ããŸãã
ã³ã³ãã€ã«ãããŸããã£ããã ãã©ãŠã¶ãã http://localhost:4000 ã«ã¢ã¯ã»ã¹ãããšè¡šç€ºã確èªã§ããã¯ãã§ãã
âã®äŸã§ã¯ãindex.jsx
ãšãããã¡ã€ã«åã«ããŠããŸããããã¡ã€ã«åã¯äœã§ãããŸããŸããã
Reactã®JSXèšæ³ãå«ãJavaScriptã¯ã.jsx
ã«ãããšããæ
£ç¿ããããŸã(æ¡åŒµåã¯åäœã«åœ±é¿ããªãã®ã§ã.js
ã§ãåé¡ãããŸãã)
ãŸããäœæããããã°ã©ã ãå®éã«å ¬éããå Žåã¯ã
npx poi build --jsx react index.jsx
ã®ããã«build
ã³ãã³ãã䜿ããŸãã./dist
以äžã«ã³ã³ãã€ã«ããããã¡ã€ã«ãçæãããã®ã§ããããããµãŒããŒã«é
眮ããŠãã ããããªããããŒã«ã«ãã¡ã€ã«ãšããŠindex.htmlãéããŠãåããªãã®ã§æ³šæããŠãã ãããHTTPãµãŒããŒçµç±ã§éãå¿
èŠããããŸãã
âïžã¯ã³ãã€ã³ã
ã³ã³ãã€ã«æã®ãšã©ãŒ(æ§æãã¹ãªã©)ã¯ãç»é¢äžã«ãšã©ãŒã衚瀺ãããã®ã§ããããããã®ã§ãããã©ã³ã¿ã€ã ãšã©ãŒãèµ·ãããšãç»é¢ãçã£çœã«ãªããªã©ãäžèŠäœãèµ·ããŠããã®ãããããªãããšããããŸãã
ããçš®ã®ã©ã³ã¿ã€ã ãšã©ãŒã¯ãJavaScriptã³ã³ãœãŒã«ã«è¡šç€ºãããã®ã§ããã¡ããåãããŠç¢ºèªããããã«ããŠã¿ãŠãã ãããChromeã®å ŽåãView -> Developer -> JavaScript Consoleã§è¡šç€ºã§ããŸãã
ãœãŒã¹ã³ãŒã
以äžã®å šãµã³ãã«ãå«ããªããžããªã
ã«çšæããã®ã§ãããã©ããªæ¹ã¯ãã¡ããæŽ»çšããŠãã ããã
Lesson 1: Hello, World
ãŸãã¯Hello, Worldããã§ãã
import React from 'react'
import ReactDOM from 'react-dom'
ReactDOM.render(<p>Hello, World!</p>, document.getElementById('app'))
å
é ã§ãReactã䜿ãããã«å¿
èŠãª2ã€ã®ã¢ãžã¥ãŒã«ãã€ã³ããŒãããŠããŸãã
次ã«ãã€ã³ããŒããã颿°ã䜿ã£ãŠãæåãæç»ããŠããŸããrender颿°ã¯ä»¥äžã®ãããª2ã€ã®ãã©ã¡ãŒã¿ãåããŸãã
ReactDOM.render(*Reactã³ã³ããŒãã³ã*, *åºåå
ã®DOMããŒã*)
Reactã§ã®ã³ãŒãã£ã³ã°ã¯ãJSXã䜿ã£ãŠèŠãç®ãèšè¿°ããŠãããŸãã
JSXãšããã®ã¯ãReactã®ããã«éçºãããç¬èªã®JavaScriptæ¡åŒµã§ãããã«ãã£ãŠãã³ãŒãå
ã«ã»ãšãã©HTMLã®ãããªã¿ã°ãçŽæ¥åã蟌ããŸãã
HTML(DOMããŒã)ã¯ã©ãã§å®çŸ©ãããŠãããã ãšäžæè°ã«æããããããããŸããããããã¯poiããããªã«å®çŸ©ããŠãããŸãã
âïžã¯ã³ãã€ã³ã
JSXã«ã¯ãéãã¿ã°ãå¿
é ã ã£ãããclass
ãclassName
ãšæžããªããã°ãªããªãã£ãããšãæ¬ç©ã®HTMLãšéãéšåãããã€ããããŸãã詳现ã¯ãã¡ãã«ãŸãšãŸã£ãŠãŸãã
å®è¡çµæ
Lesson 2: ã³ã³ããŒãã³ãã®äœæ
Reactã§ã¯ãã³ã³ããŒãã³ããšåŒã°ããããŒããèªåã§å®çŸ©ããŠãããããçµã¿åãããããšã§èŠãç®ãå®çŸ©ããŠãããŸããReactã«ãããã³ã³ããŒãã³ããšã¯ãJSXãè¿ã颿°ã§ãã
import React from 'react'
import ReactDOM from 'react-dom'
// HelloWorldã³ã³ããŒãã³ã
function HelloWorld() {
return <p>Hello, World!</p>
}
ReactDOM.render(<HelloWorld />, document.getElementById('app'))
âïžã¯ã³ãã€ã³ã
ã³ã³ããŒãã³ãã®ååã¯ãã£ã¡ã«ã±ãŒã¹ã§ãªããšã³ã³ãã€ã«ãéããŸãã
å®è¡çµæ
Lesson 3: ãã©ã¡ãŒã¿ãæž¡ã
å
ã®ã³ã³ããŒãã³ãã§ã¯ãåžžã«åãæååãè¿ãã ããªã®ã§ããªã«ãããããããããŸããã
Reactã³ã³ããŒãã³ãã¯ãprops
ãšåŒã°ããå¯äžã®åŒæ°ãåãåããŸãã
import React from 'react'
import ReactDOM from 'react-dom'
function HelloMessage(props) {
return <p>Hello, {props.target}</p>
}
ReactDOM.render(
<HelloMessage target="React!" />,
document.getElementById('app')
)
ã³ã³ããŒãã³ãã®å±æ§ãšããŠæå®ããããŒãšå€ããprops
ãšããŠã³ã³ããŒãã³ãã«æž¡ãããŸãã
äžè¿°ã®ã³ãŒãã§ã¯ã
{ target: 'React!' }
ãšãããªããžã§ã¯ããHelloMessage
ã³ã³ããŒãã³ãã«æž¡ããŠããŸãã
ãŸããJSXå
ã® {}
ã§å²ãŸããéšå(âã®äŸã ãšprops.target
)ã¯ãJavaScriptã®åŒãæžãããšãã§ããŸãã
å®è¡çµæ
âïžã¯ã³ãã€ã³ã
<MyCheckbox checked />
ã®ããã«å€ãæå®ããã«å±æ§ãèšè¿°ãããšãå€ãšããŠtrue
ãæå®ãããããšã«ãªããŸãã
Lesson 4: åèŠçŽ ãæž¡ã
props
ã®äžã«ã¯ãç¹å¥ãªæå³ãæã£ãããããã£ãŒããããŸãã
åèŠçŽ ãšããŠã¿ã°ã®å
éšã«èšè¿°ãããèŠçŽ ã衚ããprops.children
ã§ãã
import React from 'react'
import ReactDOM from 'react-dom'
function WrappingBlock(props) {
const style = {
padding: '1rem',
background: 'linear-gradient(#e66465, #9198e5)',
}
return <div style={style}>{props.children}</div>
}
ReactDOM.render(
<WrappingBlock>
<p>å²ãŸããããã¹ã</p>
</WrappingBlock>,
document.getElementById('app')
)
WrappingBlock
ã®éãã¿ã°ãšéãã¿ã°ã§å²ãŸããäžèº«(<p>å²ãŸããããã¹ã</p>
ã®éšå)ããprops.children
ãšããŠã³ã³ããŒãã³ãã«æž¡ãããŸãã
âïžã¯ã³ãã€ã³ã
style
屿§ã«CSSã®ããããã£ãŒãå«ããªããžã§ã¯ããæž¡ãããšã§çŽæ¥ã¹ã¿ã€ã«ãæå®ã§ããŸãã
å®è¡çµæ
Lesson 5: CSSã®ã¯ã©ã¹ãæå®ãã
æè¿ã®Reactãã«ãç°å¢ã§ã¯ãjsã³ãŒã以å€ã®äžè¬çãªãã¡ã€ã«ãimport
ã§åã蟌ããæ©èœãæã£ãŠããããšãå€ãã§ããã¹ã¿ã€ã«ã·ãŒããimport
ã§åã蟌ããŸãã
poiã¯ã.module.css
ãšããæ¡åŒµåãæã£ããã¡ã€ã«ããCSSã¢ãžã¥ãŒã«ãšããŠæ±ããŸããCSSã¢ãžã¥ãŒã«ã¯ãã¯ã©ã¹ã®æå¹ç¯å²ããã¡ã€ã«å
(ããŒã«ã«)ã«éå®ããŠããããããCSSã®éçšãããªãç°¡åãã€å®å
šã«ãªããŸãã
CSSã¢ãžã¥ãŒã«ãimport
ãããšãã¯ã©ã¹åãããŒã«æã€ãªããžã§ã¯ããåŸããã(äžèšã³ãŒãã®styles
)ã®ã§ããã®ããããã£ãŒãclassName
ã«æå®ããŸãã
ãã¡ãããéåžžã®ã°ããŒãã«ãªæå¹ç¯å²ãæã€ã¯ã©ã¹ã䜿çšã§ããŸããã°ããŒãã«ãªã¹ã¿ã€ã«ã·ãŒãã¯ãäžåºŠimport
ããã°ããã¹ãŠã®ã³ã³ããŒãã³ãããå©çšã§ããããã«ãªããŸãã
import React from 'react'
import ReactDOM from 'react-dom'
import './global.css'
import styles from './App.module.css'
function App() {
return (
<div className={styles.root}>
<p className="u-underlineText">ã°ããŒãã«ãªã¯ã©ã¹ã®æå®</p>
<p className={styles.root_text}>ããŒã«ã«ãªã¯ã©ã¹ã®æå®</p>
<p className={`u-underlineText ${styles.root_text}`}>
ã°ããŒãã«ãšããŒã«ã«äž¡æ¹ã®æå®
</p>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
/* global.css */
.u-underlineText {
text-decoration: underline;
}
/* App.module.css */
.root {
background: lightgray;
font-family: sans-serif;
}
.root_text {
font-weight: bold;
}
ãªããSASSã䜿ãããå Žåã¯ã以äžã®ã³ãã³ãã§è¿œå ã®ããã±ãŒãžãã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã
npm install --save-dev node-sass sass-loader
âïžã¯ã³ãã€ã³ã
ãã³ãã¬ãŒããªãã©ã«ãå©çšãããšæ¯èŒçç°¡æœã«className
ãèšè¿°ã§ããŸãã
å®è¡çµæ
Lesson 6: ã€ãã³ããåŠçãã
ãããŸã§ã§ãã³ã³ããŒãã³ãã«ãã©ã¡ãŒã¿ãäžããŠè¡šç€ºãå€åãããããšã¯ã§ããŸããããã€ã³ã¿ã©ã¯ãã£ããªèŠçŽ ã¯ãŸã£ãããããŸããã§ãããã¢ããªãã€ã³ã¿ã©ã¯ãã£ãã«ããã«ã¯ãã€ãã³ããã³ãã©ãŒã䜿ããŸãã
éåžžã®JavaScriptã§ã¯ãaddEventListener
ããonclick
, onchange
ãšãã£ã屿§ã䜿ã£ãŠãDOMãªããžã§ã¯ãã«ã€ãã³ããã³ãã©ãŒãèšå®ããŸããããããšåãããã«ãJSXã§ã¯ãonClick
, onChange
ãšãã£ãããããã£ãŒã«é¢æ°ãæž¡ããŸãã
ã€ãã³ããã³ãã©ãŒã®ã³ãŒã«ããã¯é¢æ°ã«ã¯ãevent
ãªããžã§ã¯ããæž¡ãããŸããããã¯ãéåžžã®DOMã€ãã³ããã³ãã©ãŒã«æž¡ãããevent
ãªããžã§ã¯ããšåãããã«äœ¿ããŸãã
以äžã®ãµã³ãã«ã³ãŒãã§ã¯ãã€ãã³ããã³ãã©ãŒã«ã¢ããŒé¢æ°ãçŽæ¥æž¡ããŠããŸãã
ã¢ããŒé¢æ°ã¯ES2015ã§å ãããã颿°ãçãæžããèšæ³ã§ãã
function foo(event) {
console.log(event)
}
// âã®é¢æ°ãã¢ããŒé¢æ°ã§æžããšãããªã
const foo = (event) => {
console.log(event)
}
// 颿°ã®æ¬äœã1ã¹ããŒãã¡ã³ãã®å Žåã¯{}ãçç¥ã§ãã
const foo = (event) => console.log(event)
// åŒæ°ã1ã€ã®å Žåã¯ã()ãçç¥ã§ãã
const foo = event => console.log(event)
äžèšã®é¢æ°å®çŸ©ã¯ãã©ãã(ã»ãŒ)åãæå³ã§ãã
import React from 'react'
import ReactDOM from 'react-dom'
function App() {
return (
<div>
<button onClick={() => console.log('button clicked.')}>ãã¿ã³</button>
<hr />
<label>
ããã¹ãããã¯ã¹
<input
type="text"
onChange={event =>
console.log('text changed. value =', event.target.value)
}
/>
</label>
<hr />
<label>
ã»ã¬ã¯ãããã¯ã¹
<select
onChange={event =>
console.log('select changed. value =', event.target.value)
}
>
<option value="A">éžæè¢A</option>
<option value="B">éžæè¢B</option>
<option value="C">éžæè¢C</option>
</select>
</label>
<hr />
<label>
ã©ãžãªãã¿ã³A
<input
type="radio"
name="radioButton"
value="A"
onChange={event =>
console.log('radio button clicked. value =', event.target.value)
}
/>
</label>
<label>
ã©ãžãªãã¿ã³B
<input
type="radio"
name="radioButton"
value="B"
onChange={event =>
console.log('radio button clicked. value =', event.target.value)
}
/>
</label>
<label>
ã©ãžãªãã¿ã³C
<input
type="radio"
name="radioButton"
value="C"
onChange={event =>
console.log('radio button clicked. value =', event.target.value)
}
/>
</label>
<hr />
<label>
ãã§ãã¯ããã¯ã¹
<input
type="checkbox"
onChange={event =>
console.log('checkbox changed. value =', event.target.checked)
}
/>
</label>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
å®è¡çµæ
âïžã¯ã³ãã€ã³ã
JSXã¯HTMLãšéããã¿ã°ãšããã¹ããæ¹è¡ã§åºåãããŠããå Žåã«ããã®ç©ºçœãé€å»ãããŠã¿ã°ãšããã¹ãã飿¥ããŠãã圢ã«å€æãããŸããã€ãŸãã
ããããã¹ããš
<span>èŠçŽ </span>ãæ¹è¡ã§åºåãããŠãã
ããã¯ãHTMLã ãš<span>
ã®åã«ç©ºçœæåãã²ãšã€æ®ããŸãããJSXã§ã¯ã
ããããã¹ããš<span>èŠçŽ </span>ãæ¹è¡ã§åºåãããŠãã
ãã®ããã«å€æãããŸãã
Lessen 7: ã³ã³ããŒãã³ãã«ç¶æ ãä¿æãã
ã€ãã³ããã³ããªã³ã°ã§ããŠãŒã¶ãŒæäœã«å¿ããŠåŠçãèµ°ãããããšãã§ããããã«ãªã£ãã®ã§ãä»åºŠã¯ãããã«å¿ããŠUIãå€åãããŸãã
ãã®ããã«ã¯state
ã䜿ããŸããstate
ã¯ãã³ã³ããŒãã³ãå
ã«ãªããžã§ã¯ããšããŠç¶æ
ãä¿æããŠããããã®ç¶æ
ãå
ã«UIãæ§ç¯ããããã®ä»çµã¿ã§ããsetState
颿°ã§state
ãå€åããããšãå³åº§ã«UIã«åæ ãããŸãã
ã³ã³ããŒãã³ãã«ç¶æ
ãä¿æãããããã«ã¯ãããã»ã©ãŸã§ã®é¢æ°ã«ããã³ã³ããŒãã³ãå®çŸ©ã§ã¯ãªããComponent
ãç¶æ¿ãããã¯ã©ã¹ããŒã¹ã®ã³ã³ããŒãã³ãå®çŸ©ã䜿ãå¿
èŠããããŸãã
ãšããã§ãäžèšã³ãŒãã§ã¯ã³ã³ããŒãã³ãã®åŒæ°ãprops
ã«ãªã£ãŠããŸãããããã¯ãES2015ã§å°å
¥ãããåå²ä»£å
¥ãšããæ©èœã䜿ã£ãŠãããã§ããåå²ä»£å
¥ã§ã¯ããªããžã§ã¯ããé
åã®èŠçŽ ãåå¥ã®å€æ°ã«åè§£ã§ããŸãã
const {a, b} = {a: 1, b: 2}
// a === 1 && b === 2 ã«ãªã
ããã¯ã颿°ã®åŒæ°å®£èšã§ã䜿ããã®ã§ãã€ãŸãã
const props = { name: 'aaa', address: 'bbb' }
f(props)
function f({ name, address }) {
// name === 'aaa' && address === 'bbb'
}
ãããªãã®ã§ãã
// ã¯ã©ã¹ããŒã¹ã®ã³ã³ããŒãã³ãå®çŸ©ã䜿ãããã«Componentã¯ã©ã¹ãimportããã
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
// ãŠãŒã¶ãŒå
¥åãåããããã®æ°åã»äœæãã©ãŒã
function PersonForm({ onNameChange, onAddressChange }) {
return (
<form>
<label>
æ°å: <input type="text" onChange={onNameChange} />
</label>
<label>
äœæ: <input type="text" onChange={onAddressChange} />
</label>
</form>
)
}
// æ°åãšäœæã衚瀺ããããã®ã³ã³ããŒãã³ã
function PersonInfo({ name, address }) {
const tableStyle = {
borderCollapse: 'collapse',
}
const cellStyle = {
border: 'solid black 1px',
height: '1rem',
padding: '0.3rem',
}
return (
<table style={tableStyle}>
<thead>
<tr>
<th style={cellStyle}>æ°å</th>
<th style={cellStyle}>äœæ</th>
</tr>
</thead>
<tbody>
<tr>
<td style={cellStyle}>{name}</td>
<td style={cellStyle}>{address}</td>
</tr>
</tbody>
</table>
)
}
// ã¯ã©ã¹ããŒã¹ã®ã³ã³ããŒãã³ãå®çŸ©ãAppã³ã³ããŒãã³ãã¯ãComponentã¯ã©ã¹ãç¶æ¿ããã
class App extends Component {
// 颿°ã«ããã³ã³ããŒãã³ãå®çŸ©ã§ã¯ãpropsã颿°ã®åŒæ°ãšããŠåãåã£ãŠãããã
// ã¯ã©ã¹ããŒã¹ã®å Žåã¯ãã³ã³ã¹ãã©ã¯ã¿ã®åŒæ°ãšããŠåãåãã
constructor(props) {
// åãåã£ãpropsã¯èŠªã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã«ãã®ãŸãŸæž¡ã
super(props)
// stateã®åæå€ãå®çŸ©ãããstateã¯ãªããžã§ã¯ãã§è¡šçŸãããã
this.state = {
name: '',
address: '',
}
}
// ã€ãã³ããã³ãã©ã§ãŠãŒã¶ãŒå
¥åãåãããããã®å€ã䜿ã£ãŠstateãæŽæ°ãã
// stateãæŽæ°ããããã«ã¯ãçŽæ¥å€ã代å
¥ããŠã¯ãããªããå¿
ãthis.setStateã§æŽæ°ããå¿
èŠãããã
handleNameChange = ev => {
this.setState({ name: ev.target.value })
}
handleAddressChange = ev => {
this.setState({ address: ev.target.value })
}
// stateã®å€ãå
ã«PersonInfoãã¬ã³ããªã³ã°ãã(this.state.name, this.state.address)
render() {
return (
<div>
<PersonForm
onNameChange={this.handleNameChange}
onAddressChange={this.handleAddressChange}
/>
<hr />
<PersonInfo name={this.state.name} address={this.state.address} />
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
âïžã¯ã³ãã€ã³ã
extends Component
ãšãã代ããã«ãextends PureComponent
ãšãããšããã®ã³ã³ããŒãã³ãã¯ããã©ãŒãã³ã¹çãªæé©åã®æœãããã³ã³ããŒãã³ãã«ãªããŸãããã®å Žåãæ¬¡ã®ãããªé çªã§åŠçãé²ã¿ãŸã:
- æ°æ§ã®
props
ãšstate
ãæ¯èŒããŠãéããæ€åºããããæ¬¡ã«é²ã(ãããªããã°ã¹ããã) - æ°æ§ã®(å éšçãª)DOMæ§é ãæ¯èŒããŠãéããæ€åºããããæ¬¡ã«é²ã(ãããªããã°ã¹ããã)
- å®éã®DOMæ§é ã倿Žãã
ãŸããåŸè¿°ã®react-reduxã®connectã§ã©ãããããã³ã³ããŒãã³ãã§ãããããšäŒŒããããªæé©åãè¡ãããŸãã
ãšããããã€ãã³ããã³ãã©ãšããŠãLesson 6ã®ããã«å¿å颿°ãæž¡ããšãæ¯åæ°ãã颿°ã®ã€ã³ã¹ã¿ã³ã¹ãçæãããŠããŸããæå³ãšããŠã¯åã颿°ãæž¡ããŠããã€ããã§ãã1ã®ã¹ãããã§éããšå€å®ãããŠDOMæ§é ã®æ¯èŒãçºçããŠããŸããŸã(ããªãŒã倧ããå Žåã¯ãããªãã®ã³ã¹ãã䌎ãåŠçã§ã)ã
<input>
ã®ãããªåäžDOMèŠçŽ ã§ããã°ããããã2ã®æ¯èŒã¹ãããèªäœããªãã®ã§åé¡ãªãã§ãããè€åçãªã³ã³ããŒãã³ãã§ã¯ãæœåšçã«ããã©ãŒãã³ã¹ã®åé¡ãã¯ããã§ããŸããããã§ãâã®ã³ãŒãã§ã¯ãã€ãã³ããã³ãã©ãã¡ãœããã§å®çŸ©ããŠããã®ã§ããäžè¬çã«ãã³ã³ããŒãã³ãã«å¯ŸããŠã³ãŒã«ããã¯ãå®çŸ©ãããšãã«ã¯ãå¿å颿°ã§ã¯ãªãã¡ãœããã§å®çŸ©ããŠãããã»ããç¡é£ã§ãã
å®è¡çµæ
Lessen 8: æ¡ä»¶ã«å¿ããŠè¡šç€ºããèŠçŽ ãå€ãã
JSXã®{}
å
ã«ã¯åŒããèšè¿°ã§ããªããããif
ã®ãããªå¶åŸ¡æ§æã¯çœ®ããŸããã
ãã®ãããprops
ãstate
ã«å¿ããŠãåºåããèŠçŽ ãå€ããããšãã«ã¯ãäžé
æŒç®å(a ? b : c
)ã䜿ããŸãã
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor(props) {
super(props)
this.state = {
checked: false,
}
}
render() {
return (
<div>
<label>
Reactãããã£ãŠãã<input
type="checkbox"
onChange={event => this.setState({ checked: event.target.checked })}
/>
</label>
<br />
{this.state.checked ? (
<img src="https://media.giphy.com/media/11ISwbgCxEzMyY/giphy.gif" />
) : (
<p>Reactãã£ãŠãããŸããã</p>
)}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
ãã¡ãããJSXã®å€åŽã§ãµã€ãã«ifæã䜿ã£ãŠãããŸããŸããã
æ¡ä»¶ãè€éã«ãªãå Žåã¯ããã¡ãã®ã»ããããã§ãããã
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class App extends Component {
constructor(props) {
super(props)
this.state = {
checked: false,
}
}
render() {
let variableElement
if (this.state.checked) {
variableElement = (
<img src="https://media.giphy.com/media/11ISwbgCxEzMyY/giphy.gif" />
)
} else {
variableElement = <p>Reactãã£ãŠãããŸããã</p>
}
return (
<div>
<label>
Reactãããã£ãŠãã<input
type="checkbox"
onChange={event => this.setState({ checked: event.target.checked })}
/>
</label>
<br />
{variableElement}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
âïžã¯ã³ãã€ã³ã
<MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
ãã®JSXã¯ã
React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)
ãã®ãããªJavaScriptã³ãŒãã«å€æãããŸãã
JSXãšèšãã©ããã ã®ãªããžã§ã¯ããªã®ã§ããµã€ãã«å€æ°ã«å
¥ããããŸãã
Lesson 9: ãªã¹ãã衚瀺ãã
é
åã«æ ŒçŽãããå€ãå
ã«ã³ã³ããŒãã³ãã®ãªã¹ãã衚瀺ãããšãã«ã¯ãmap
ã䜿ããŸãã
ã³ã³ããŒãã³ãã®é
åãã¬ã³ããªã³ã°ãããšãã«ã¯ãåèŠçŽ ã«å€ã®è¢«ããªãkey
ããããã£ãŒãæå®ããå¿
èŠããããŸãã
import React from 'react'
import ReactDOM from 'react-dom'
const cats = [
{ id: 1, name: 'mee' },
{ id: 2, name: 'gomoku' },
{ id: 3, name: 'tama' },
{ id: 4, name: 'mike' },
{ id: 5, name: 'mikael' },
]
function HelloMessage(props) {
return <p>Hello, {props.target}</p>
}
function App(props) {
return (
<ul>
{cats.map(cat => (
<li key={cat.id}>
<HelloMessage target={cat.name} />
</li>
))}
</ul>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
å®è¡çµæ
âïžã¯ã³ãã€ã³ã
key
ããããã£ãŒãšããŠãé
åã®ã€ã³ããã¯ã¹ãæå®ããã®ã¯ãéæšå¥šã§ã(eslintãªã©ã§ã¯èŠåã衚瀺ãããŸã)ã
ããããããšããªã¹ãã®èŠçŽ ã䞊ã³ãããããèŠçŽ ãæ¿å
¥ããããããšãã«ãããã©ãŒãã³ã¹ãäžãã£ãããè¡šç€ºçµæããããããªãããšãããããã§ãããã®ãããé
åèŠçŽ ã«ã¯ããã®èŠçŽ ãç¹å®ã§ããäœããã®å€ãæ ŒçŽããŠããå¿
èŠããããŸãã
çªå€ç·š: Reduxã§ç¶æ ã管çãã
å°æ¥ã®ããšã¯ããããŸãããããããªããšãçŸæç¹ã«ãããŠãReactã¢ããªéçºã®çŸå Žã§ã¯ãReduxãšããç¶æ 管çã®ããã®ã©ã€ãã©ãªã䜵çšãããããšãå€ããšæããŸãã
詊ãã«Lesson 7ã®ã³ãŒããReduxåããŠã¿ãŸããReduxã䜿ãããã«ã¯è¿œå ããã±ãŒãžã2ã€å¿ èŠã§ãã
npm install --save redux react-redux
Reduxãå
¥ããšãæŠå¿µçã«ãã³ãŒãçã«ãäžæ°ã«è€éã«ãªããŸãã
ããèªäœãéåžžã«å¥¥æ·±ãããŒããªã®ã§ãããã§ã¯è©³çްãªèª¬æã¯ããŸããã
Reduxå°å ¥ã®ã¡ãªãããšããŠæããŠããããšãåæãããš:
- ã¢ããªç¶æ 倿ŽãActionãšããæŠå¿µã§ãŸãšããããã®ã§ãèŠéããè¯ããªã
- propsã®ãã±ããªã¬ãŒãé¿ãããã(Reduxããã±ããªã¬ãŒãé¿ããå¯äžã®ææ®µãšããæå³ã§ã¯ãªãã§ã)
- PureComponentãšäŒŒãããã©ãŒãã³ã¹æé©åãèªåçã«åŸããã
- 匷åãªãããã°ããŒã«ãä»ããŠãã
ãšãã£ãæãã§ãã
Reduxãå°å
¥ãããšãäžå³ã®ããã«ç¶æ
ã®çœ®ãå Žæãšæµããå€ãããŸãã
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux'
// ã¢ã¯ã·ã§ã³ãå®çŸ©ãã
const CHANGE_NAME = 'CHANGE_NAME'
const CHANGE_ADDRESS = 'CHANGE_ADDRESS'
// ã¢ã¯ã·ã§ã³ã¯JavaScriptãªããžã§ã¯ãã§è¡šçŸãããã
// ã¢ã¯ã·ã§ã³ãçæããããã®Action CreatorãšåŒã°ãã颿°ãå®çŸ©ããã
function createChangeName(name) {
return {
type: CHANGE_NAME,
payload: {
name,
},
}
}
function createChangeAddress(address) {
return {
type: CHANGE_ADDRESS,
payload: {
address,
},
}
}
// ã¢ããªã®åæç¶æ
const initialState = {
name: '',
address: '',
}
// ã¢ããªã®ç¶æ
倿Žã¯ãReducerãšåŒã°ãããçŽç²é¢æ°ãã§å®çŸ©ãããã
// çŽç²é¢æ°ãªã®ã§åŒæ°ã倿ŽããŠã¯ãããªãã
function reducer(state = initialState, action) {
switch (action.type) {
case CHANGE_NAME:
return {
...state,
name: action.payload.name,
}
case CHANGE_ADDRESS:
return {
...state,
address: action.payload.address,
}
default:
return state
}
}
// PersonForm,PersonInfoã³ã³ããŒãã³ãã¯Lesson 7ã§å®çŸ©ãããã®ãšãŸã£ããåãã
function PersonForm({ onNameChange, onAddressChange }) {
return (
<form>
<label>
æå: <input type="text" onChange={onNameChange} />
</label>
<label>
äœæ: <input type="text" onChange={onAddressChange} />
</label>
</form>
)
}
function PersonInfo({ name, address }) {
const tableStyle = {
borderCollapse: 'collapse',
}
const cellStyle = {
border: 'solid black 1px',
height: '1rem',
padding: '0.3rem',
}
return (
<table style={tableStyle}>
<thead>
<tr>
<th style={cellStyle}>æ°å</th>
<th style={cellStyle}>äœæ</th>
</tr>
</thead>
<tbody>
<tr>
<td style={cellStyle}>{name}</td>
<td style={cellStyle}>{address}</td>
</tr>
</tbody>
</table>
)
}
// ã³ã³ããŒãã³ãããã¢ããªã®ã°ããŒãã«ãªç¶æ
ãä¿æãããStoreãšæ¥ç¶ããã
// mapStateToPropsã¯ãStoreãããã³ã³ããŒãã³ãã«æž¡ãpropsãæãåºã颿°
function mapStateToProps(state) {
return {
name: state.name,
address: state.address,
}
}
const PersonInfoConnected = connect(mapStateToProps, null)(PersonInfo)
function mapDispatchToProps(dispatch) {
return {
onNameChange: event => dispatch(createChangeName(event.target.value)),
onAddressChange: event => dispatch(createChangeAddress(event.target.value)),
}
}
const PersonFormConnected = connect(null, mapDispatchToProps)(PersonForm)
// Appã³ã³ããŒãã³ãã¯ãèªèº«ã§`state`ãæããªããªã£ãã®ã§ã¹ãããªããã
function App() {
return (
<div>
<PersonFormConnected />
<hr />
<PersonInfoConnected />
</div>
)
}
// Storeã€ã³ã¹ã¿ã³ã¹ãçæããŠãAppã³ã³ããŒãã³ãã®å€åŽã«é
眮ããã
// ããã§ãå
åŽã®ããªãŒã®ã©ãããã§ããStoreãåç
§ã§ããããã«ãªãã
const store = createStore(reducer)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app')
)
å®è¡çµæ
åè
-
ã¡ãªã¿ã«ãèšå®äžèŠã§Reactãåãããç°å¢ã¯ãcreate-react-app, parcel, codesandboxãªã©ãpoi以å€ã«ããããããªãã®ããããŸãã â©