React Redux
Vue.jsのVuexと似てるけど、こんなんだったっけな。
import React from 'react'; import QuxComponent from '../QuxComponent/QuxComponent'; import { createStore } from 'redux'; import { Provider } from 'react-redux'; const BazComponent = () => { const initial_state = { a: 1, b: 2, c: 3, } const reducer = (state = initial_state, action) => { switch (action.type) { case 'increment': return { ...state, a: state.a + 1, b: state.b * 2, } default: return state } } const store = createStore(reducer) return ( <div className="App"> BazComponent<br/> <Provider store={store}> <QuxComponent/> </Provider> </div> ) }; export default BazComponent;
import React, { Component } from 'react'; import { connect } from 'react-redux'; class QuxComponent extends Component { constructor (props) { super(props) this.doAction = this.doAction.bind(this) } doAction () { this.props.dispatch({ type: 'increment' }) } render () { return ( <div className="App"> QuxComponent Component <div>{this.props.a}</div> <div>{this.props.b}</div> <div>{this.props.c}</div> <button onClick={this.doAction}>increment</button> </div> ) } } QuxComponent = connect(state => state)(QuxComponent) export default QuxComponent;
React hooks useContext 切り出し
切り出されたコンテキスト。
import React, { useState, createContext } from 'react'; export const QuxContext = createContext() export function QuxContextProvider(props) { const [value, setValue] = useState(0) return ( <QuxContext.Provider value={[value, setValue]}> {props.children} </QuxContext.Provider> ) }
親、子、孫コンポーネント。
import React from 'react'; import BarComponent from '../BarComponent/BarComponent'; import { QuxContextProvider } from '../../QuxContext'; const FooComponent = () => { return ( <div className="App"> FooComponent <QuxContextProvider> <BarComponent/> </QuxContextProvider> </div> ) }; export default FooComponent;
import React, { useContext, useState } from 'react'; import BazComponent from '../BazComponent/BazComponent'; import { QuxContext } from '../../QuxContext'; const BarComponent = () => { const [value, setValue] = useContext(QuxContext) return ( <div className="App"> BarComponent <div><button onClick={() => setValue(value + 1)}>increment</button></div> <div>{value}</div> <BazComponent /> </div> ) }; export default BarComponent;
import React, { useContext, useState } from 'react'; import { QuxContext } from '../../QuxContext'; const BazComponent = () => { const [value, setValue] = useContext(QuxContext) return ( <div className="App"> BazComponent<br/> <div><button onClick={() => setValue(value + 1)}>increment</button></div> <div>{value}</div> </div> ) }; export default BazComponent;
React hooks useContext
え、useContextがあったらReduxいらないってこと…?
import React, { useState, useEffect } from 'react'; import BarComponent from '../BarComponent/BarComponent'; export const UserCount = React.createContext() const FooComponent = () => { const [count, setCount] = useState(0) return ( <div className="App"> FooComponent Component<br /> <button onClick={() => setCount(count + 1)}>increment</button> <UserCount.Provider value={[count, setCount]}> <BarComponent /> </UserCount.Provider> </div> ) }; export default FooComponent;
import React from 'react'; import BazComponent from '../BazComponent/BazComponent'; const BarComponent = () => ( <div className="App"> BarComponent Component <BazComponent /> </div> ); export default BarComponent;
import React, {useContext} from 'react'; import { UserCount } from '../FooComponent/FooComponent'; const BazComponent = () => { const [count, setCount] = useContext(UserCount) return ( <div className="App"> BazComponent Component<br /> <button onClick={() => setCount(count + 1)}>increment</button> <div>{count}</div> </div> ) }; export default BazComponent;
React hooks useEffect
え、useEffect便利すぎへん?
Vue.js3未満にそういう機能ないように思うけど…。
Vue.js3(Vue-next)が出るまで、完全にReactがリードしてるような…。
increment1のボタンをクリックした時のみ、コンソールが出力される。
import React, { useState, useEffect } from 'react'; const FooComponent = () => { const [count1, setCount1] = useState(0) const plusOne1 = () => setCount1(count1 + 1) const [count2, setCount2] = useState(0) const plusOne2 = () => setCount2(count2 + 1) useEffect(() => { console.log(123) }, [count1]); return ( <div className="App"> <div> <button onClick={plusOne1}>increment1</button> </div> <div>{count1}</div> <div> <button onClick={plusOne2}>increment2</button> </div> <div>{count2}</div> </div> ) }; export default FooComponent;
React hooks 全て選択チェックボックス
import React, { useState } from 'react'; const FooComponent = () => { const [a, setA] = useState(true) const [b, setB] = useState(true) const [c, setC] = useState(true) const selectAll = (e) => { let bool = e.target.checked ? true : false setA(bool) setB(bool) setC(bool) } return ( <div className="App"> <div> A<input type="checkbox" checked={a} onChange={() => setA(!a)} /> B<input type="checkbox" checked={b} onChange={() => setB(!b)} /> C<input type="checkbox" checked={c} onChange={() => setC(!c)} /> </div> <div> All<input type="checkbox" onChange={selectAll} checked={a && b && c}/> </div> </div> ) }; export default FooComponent;
React hooks useState
Reactのクラスコンポーネントを触ってみたが、双方向データバインディングのあるVue.jsに比べて使いにくすぎて驚いた。
ただ、Hooksは使いやすい。これなら、Reactでも普通に使っていけそう。
import React, { useState } from 'react'; const FooComponent = () => { const [count, setCount] = useState(0) const double = () => setCount(count * 2) return ( <div className="App"> <button onClick={() => setCount(count + 1)}>increment</button><br /> <button onClick={double}>double</button> <div>{count}</div> </div> ) }; export default FooComponent;
Angular FormArray
配列で動的にフォーム生成したい時は、FormArrayを使う。
farray = this.fb.array([ true, false, true, ])
<input type="checkbox" [formControl]="farray.at(0)"> <input type="checkbox" [formControl]="farray.at(1)"> <input type="checkbox" [formControl]="farray.at(2)"> <div>a: {{farray.at(0).value}}</div> <div>b: {{farray.at(1).value}}</div> <div>c: {{farray.at(2).value}}</div>