react-ele-webapp
项目地点 :https://github.com/kliuj/reac…
run
下载完项目
npm install
然后
npm run dev
即可
基于 react react-router redux
的项目,重如果为了进修实战react
。数据都是牢固的,从饿了么接口暂时抓的,模仿了一个0-100ms
的异步数据耽误,谢谢饿了么。
以下内容是项目开辟的历程和一些思索,根据这个历程最少能保证完成一个相对完全的react
百口桶项目
内容参考
react
文档:http://reactjs.cn/react/docs/…
react-router
文档地点 :https://reacttraining.com/rea…
react-router
中文版参考:http://www.uprogrammer.cn/rea…
redux
文档参考:http://redux.js.org/
redux
中文文档:http://cn.redux.js.org/
搭建项目:
竖立项目目次,装置package.json,设置webpack.config
做好基本依靠事情,摘自package.json的一部分内容
"devDependencies": {
"babel-core": "^6.23.1",
"babel-loader": "^6.4.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.23.0",
"html-webpack-plugin": "^2.28.0",
"jshint": "^2.9.4",
"jshint-loader": "^0.8.4",
"react": "^15.2.0",
"react-dom": "^15.2.0",
"react-router": "^2.0.0",
"redux": "^3.6.0",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.1"
} //JAVASCRIPT
项目模块构造构造一些基本事情
最先举行开辟一个项目除了手艺选型以外,另有许多基本东西要先设想好,一个好的构造设想要可认为今后的进步事情效率。我这方面另有许多短缺,现在重要斟酌了3个模块的设想:
1:背景接口通讯层:
model.js
重要处置惩罚一致接口的要求发送和回调,放在一同更有利于后期保护,也增添可阅读性
//接口对应的url,这里只做演示
const uris = {
index_entry : fetchData.index_entry,
hot_search_words : fetchData.hot_search_words
}
//接口挪用层
export default function send(url,postData,successCallback,errCallback){
//模仿耽误,假接口
let promise = new Promise(function(resolve,reject){
setTimeout(function(){
resolve(fetchData[url])
},Math.random()*100)
})
promise.then(function(data){
successCallback(data)
})
}
2:当地数据缓存保护:
baseStore.js
重要处置惩罚页面之间的跳转返回,增添更多的自主性和扩展性
// 自动存储阅读纪录
export function saveFrom(prop) {
let name = prop.pagename,
transit = prop.location,
qhfrom = transit.query.qhfrom ,//默许悉数返回首页
para = transit.query.para ? JSON.parse(transit.query.para) : '';
if(!qhfrom) return false;
let paths = localStorage.getItem("FromUrlStore") ? JSON.parse(localStorage.getItem("FromUrlStore")) : {};
if (localStorage) {
paths[name] = {
'name':qhfrom,//存储泉源页面
'para':para //存储泉源页面的参数
}
localStorage.setItem("FromUrlStore", JSON.stringify(paths));
}
}
//存储页面的泉源,一致管理
3:大众要领的处置惩罚:
baseFun.js
重要用来定义一些公用的模块要领
//安排公用函数
export function showToast(){
...
}
运用react-router初始化页面
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link,hashHistory ,IndexRedirect,IndexRoute} from 'react-router'
import Home from './components/home.jsx'
import Discover from './components/discover.jsx'
const App = React.createClass({
render() {
return (
<div>
<footer>
<Link to="/home">外卖</Link>
<Link to="/discover?qhfrom=home">发明</Link>
</footer>
{this.props.children}
</div>
)
}
})
const route = (
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="home" component={Home} />
<Route path="discover" component={Discover} />
</Route>
</Router>
)
render(route, document.getElementById("app"))
代码简朴引见:
由于没有背景,采纳的 hashHistory
(hash
路由),关于hash
路由能够参考:https://github.com/kliuj/spa-… 有简朴的引见。
这个是router的跳转 <Link to="/home">外卖</Link>
这个是加载子路由组件 {this.props.children}
这个是默许的跳转页面 <IndexRoute component={Home} />
处置惩罚首页的转动列表
首页重要分成了4个组件
底部导航 + 转动列表 + 单个产物 + 首页搜刮框
转动列表封装了一个简朴的组件
<List
list={Pro} //每一个产物item组件
pagename={'home'} //跳转产物列表的上级页面 用来处置惩罚返回
data={this.state.productList} //须要衬着的数据
onScroll = {this.getMore.bind(this)}//转动加载函数
/>
在scrollList组件内里监听了转动事宜举行自动加载的处置惩罚
react-redux 处置惩罚登录和登出
运用redux的缘由:用户信息和登录是两个差别的组件,也没有父子级的关联,然则须要举行数据状况同享和相互影响。详细信息能够看上面的官方文档,我这里就简朴说一下我这个项目的运用。
定义常量
actionTypes.js
//登入胜利
export const LOG_SUCCESS = 'LOG_SUCCESS'
//正在登录
export const LOG_ING = 'LOG_ING'
//注销登录
export const LOG_OUT = 'LOG_OUT'
//重如果一致保留状况对应的称号
定义详细的触发操纵
actions/login.js
//注销 同步
export function log_out (){
return {
type:actionTypes.LOG_OUT
}
}
//登入 异步
export function log_in (obj){
return dispatch=>{
//pending 正在举行登录的状况
dispatch({type:actionTypes.LOG_ING})
//最先发送异步要求登录
new Promise((resolve,reject)=>{
...
}).then(res=>{
dispatch(res)
})
}
}
//异步状况须要运用中间件
处置惩罚数据
reducers/login.js
export default function(state = initialData,action){
switch(action.type){
case actionTypes.LOG_SUCCESS:
return {
loginstate:1,
username:action.username
}
break
case actionTypes.LOG_ING:
return{
loginstate:-1,
username:'正在登录'
}
case actionTypes.LOG_OUT:
return initialData
break
default :
return initialData
}
}
运用中间件建立store层
store/store.js
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
//兼并的多个reducer,解耦
import rootReducer from '../reducers/index.js'
const middlewares = [thunk]
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore)
export default function configureStore(initialState){
return createStoreWithMiddleware(rootReducer,initialState)
}
在路由层引入
import {Provider} from 'react-redux'
const store = configureStore()
const route = (
<Provider store={store}>
<Router history={hashHistory}>
...
</Router>
</Provider>
)
组件内里运用
import { connect } from 'react-redux'
import {log_out} from '../../actions/login.js' //操纵
...
...
function mapStateToProps(userinfo){
let {login} = userinfo //这个是返回的一切reducer,我们只用当前须要的,参考 reducers/index.js 内容
return login
}
export default connect(mapStateToProps)(UserInfo)
//这个时刻就能够在当前组件状况的 this.props 获取到这个 login 数据,
//操纵的时刻
const {dispatch} = this.props;
dispatch(log_out())
//这时刻就能够操纵redux状况的数据,每次数据转变都邑下发给一切吸收的组件