上一節中<App/>組件傳遞狀態temperatures給children -- <TemperatureInput />,若是組建是一個tree, 那麼屬性的傳遞則會很是繁瑣。redux使用Provider給子組件提供store, connect將子組件和store聯繫起來,mobx使用Provider和inject注入javascript
import ReactDOM from 'react-dom' // import registerServiceWorker from './registerServiceWorker'; import React from 'react' import { action, computed, observable } from 'mobx' import { Provider, observer, inject } from 'mobx-react' import DevTools from 'mobx-react-devtools' const APPID = '415a88f2b45f08c3e561b058772ec6c3' class Temperature { id = Math.random() @observable unit = 'C' @observable temperatureCelsius = 25 @observable location = 'Amsterdam, NL' @observable loading = true constructor (location) { this.location = location this.fetch() } @computed get temperatureKelvin () { console.log('calculating Kelvin') return this.temperatureCelsius * (9 / 5) + 32 } @computed get temperatureFahrenheit () { console.log('calculating Fahrenheit') return this.temperatureCelsius + 273.15 } @computed get temperature () { console.log('calculating temperature') switch (this.unit) { case 'K': return this.temperatureKelvin + '°K' case 'F': return this.temperatureFahrenheit + '°F' case 'C': return this.temperatureCelsius + '°C' default: return this.temperatureCelsius + '°C' } } @action fetch () { window.fetch(`http://api.openweathermap.org/data/2.5/weather?appid=${APPID}&q=${this.location}`) .then(res => res.json()) .then(action(json => { this.temperatureCelsius = json.main.temp - 273.15 this.loading = false })) } @action setUnit (newUnit) { this.unit = newUnit } @action setCelsius (degrees) { this.temperatureCelsius = degrees } @action('update temperature and unit') setTemperatureAndUnit (degrees, unit) { this.setUnit(unit) this.setCelsius(degrees) } @action inc() { this.setCelsius(this.temperatureCelsius + 1) } } @inject('temperatures') @observer class TemperatureInput extends React.Component { @observable input = '' render () { return ( <li> Destination <input value={this.input} onChange={this.onChange}/> <button onClick={this.onSubmit}>Add</button> </li> ) } @action onChange = e => { this.input = e.target.value } @action onSubmit = () => { this.props.temperatures.push(new Temperature(this.input)) this.input = '' } } @observer class TView extends React.Component { render () { const t = this.props.temperature return ( <li key={t.id} onClick={() => this.onTemperatureClick()}>{t.location}: {t.loading ? 'loading...' : t.temperature}</li> ) } @action onTemperatureClick = () => { this.props.temperature.inc() } } const App = inject('temperatures')(observer( ({ temperatures }) => ( <ul> <TemperatureInput /> {temperatures.map(t => <TView key={t.id} temperature={t} /> )} <DevTools/> </ul> ))) const temps = observable([]) ReactDOM.render( <Provider temperatures={temps}> <App /> </Provider>, document.getElementById('root') )