1. 程式人生 > >Be Close To The Real World

Be Close To The Real World

color p s browser outer bject 能夠 oot res inject

ps: 最近在學react和redux。用了幾天時間看了下,個人覺得react本身比較易懂,但是涉及到的各種中間件和api讓人腦闊疼(正好前段時間用vue+koa寫了個簡易的博客,對中間件還算理解)。在看到redux的時候,被這個real world的栗子難住了(個人水平太low)還2天過年,心思也不在這了。本來想放棄了,後來想想年後就辭職找工作了(心芳芳)新的風暴已經出現,怎麽能夠停滯不前。硬著頭皮看下代碼吧!

栗子目錄是醬紫的....,咱們剝洋蔥(衣服)一樣,慢慢深入。

技術分享圖片

根目錄下的index.js ( Root模板,store數據和邏輯 )

import React from ‘react‘ 
import { render } from 
‘react-dom‘   import { BrowserRouter as Router } from ‘react-router-dom‘ import Root from ‘./containers/Root‘ import configureStore from ‘./store/configureStore‘ const store = configureStore(); render( <Router> <Root store={store} />  // 由頂層傳入store,謹記redux三大原則(單一store,store改變必須由dispatch來通知,reducer最好是pure函數
) </Router>, document.getElementById(‘root‘) );

/containers/Root ( 就2行代碼,根據運行環境切換輸出 )

if (process.env.NODE_ENV === ‘production‘) {
  module.exports = require(‘./Root.prod‘)
} else {
  module.exports = require(‘./Root.dev‘)
}

/containers/Root.dev.js

import React from ‘react‘
import PropTypes from 
‘prop-types‘  // props類型檢查 import { Provider } from ‘react-redux‘ // 包裝函數,用於將redux和react鏈接起來 import DevTools from ‘./DevTools‘  // 可視化調試工具,用法簡單 import { Route } from ‘react-router-dom‘  // 路由 import App from ‘./App‘ import UserPage from ‘./UserPage‘ import RepoPage from ‘./RepoPage‘ const Root = ({ store }) => ( <Provider store={store}> <div> <Route path="/" component={App} /> <Route path="/:login/:name" component={RepoPage} /> <Route path="/:login" component={UserPage} /> <DevTools /> </div> </Provider> ) Root.propTypes = { store: PropTypes.object.isRequired, } export default Root

/containers/APP.js ( 頂層邏輯,react是單向數據流,由高流向低( 父->子->孫 ) )

import React, { Component } from ‘react‘
import PropTypes from ‘prop-types‘
import { connect } from ‘react-redux‘
import { withRouter } from ‘react-router-dom‘
import Explore from ‘../components/Explore‘
import { resetErrorMessage } from ‘../actions‘

class App extends Component {
static propTypes = {
// Injected by React Redux
errorMessage: PropTypes.string,
resetErrorMessage: PropTypes.func.isRequired,
inputValue: PropTypes.string.isRequired,
// Injected by React Router
children: PropTypes.node  // 由路由註入?怎麽個註入法?
};

handleDismissClick = e => {
this.props.resetErrorMessage();
e.preventDefault()
};

handleChange = nextValue => {
this.props.history.push(`/${nextValue}`)
};

renderErrorMessage() {
const { errorMessage } = this.props;
if (!errorMessage) {
return null
}

return (
<p style={{ backgroundColor: ‘#e99‘, padding: 10 }}>
<b>{errorMessage}</b>
{‘ ‘}
<button onClick={this.handleDismissClick}>
Dismiss
</button>
</p>
)
}

render() {
const { children, inputValue } = this.props;
return (
<div>
<Explore value={inputValue}
onChange={this.handleChange} />
<hr />
{this.renderErrorMessage()}
{children}
</div>
)
}
}

const mapStateToProps = (state, ownProps) => ({  // 訂閱Store,每當state變化時就會重新渲染。第一個參數是Store,第二個參數是當前組件的props對象,props改變也會重新渲染
errorMessage: state.errorMessage,
inputValue: ownProps.location.pathname.substring(1)  // 必須要ownProps.location.pathname才能拿到path嗎,反正path變化會觸發渲染,類似Vue的watch router
});

export default withRouter(connect(mapStateToProps, {  // withRouter可以包裝任何自定義組件,無需一級級傳遞react-router屬性,就可以拿到需要的路由信息
resetErrorMessage
})(App)

Be Close To The Real World