react+redux+es6

来源:互联网 发布:ubuntu设置不休眠 编辑:程序博客网 时间:2024/05/21 17:13

react+redux+es6

最近做项目用的是react+redux框架,在这里记录一下,以后如果再用到就可以快速上手。项目的整体框架图如下:

这里写图片描述

由于框架的具体内容太多,这里不讨论如何搭建框架,只讲述react+redux部分
redux的原理如下:
这里写图片描述
完整的流程是:视图层发出action,调用纯函数reducer重新计算值,数据源store发生改变,state状态发生改变,组件重新渲染,视图得到更新。在action里向后台服务器请求数据,并处理响应。

让我们看看如何做下面这样一个页面:

这里写图片描述

根据react的“万物皆组件”思想,首先我们将该页面分为几个组件:
这里写图片描述
一般来说,每个页面都有其单独的store。为了以热加载的形式调试新页面,我们要把store文件夹下创建新的store,并使用中间件applyMiddleware

export default initialState => {  const store = applyMiddleware(thunk)(createStore)(reducer, initialState)  //热替换选项  if (module.hot) {    // Enable Webpack hot module replacement for reducers    module.hot.accept('../reducers/news', () => {      const nextReducer = require('../reducers/news')      store.replaceReducer(nextReducer)    })  }  return store}

然后,我们要去配置一个单页应用的入口,在entry下创建news.js

render(     <Provider store={store}>    <Router history={history}>        <Route component={IndexHeader}>            <Route component={IndexFooter}>              <IndexRoute component={IndexContainer}/>              <Route path="/news" component={IndexContainer} />              <Redirect from='*' to='/news' />            </Route>        </Route>      </Router>    </Provider>,    document.getElementById('root')   )

在这里,如果有子页面,就通过路由来访问不同的组件容器。
接下来,编写组件容器,在containers.js下创建news文件夹并添加news_container.js文件

function mapStateToProps(state) {  return {    newsState: state.payload,  }}//将action的所有方法绑定到props上function mapDispatchToProps(dispatch) {  return bindActionCreators(NewsAction, dispatch)}//通过react-redux提供的connect方法将我们需要的state中的数据和actions中的方法绑定到props上export default connect(mapStateToProps, mapDispatchToProps)(NewsComponent)

这之后,我们就要写action和component了
第一个首先要定义数据结构,即页面的数据中心。在reducers下创建news文件夹,并创建news_reducer.js

export default function show(state = {  keyWord:'',  searchList: [],  hotList: [],  userInfo: '',}, action) {  switch (action.type) {    case CASHDATA:      return {        keyWord:action.keyWord,        searchList:action.searchList,        hotList:action.hotList,        userInfo:action.userInfo,       }      break    default:      return state  }}

第二个是在action下新建news文件夹,并添加news_action.js

//初始化视图export function initData() {  return (dispatch,getState)=> {    const{newsState}=getState()    $.post('/getInitData', {        keyWord:'新闻',       }).done(function(data) {      newsState['keyWord']=data.keyWord      newsState['searchList']=data.searchList      newsState['hotList']=data.hotList      cashState['userInfo']=data.userInfo      dispatch(actionCreator(NEWS,newsState))    }).fail(function(err) {      console.log(err)    });  }}

第三就是写组件了,在component下创建news文件夹,并创建news_component.js文件

class NewsComponent extends Component {  constructor(props) {    super(props);    props.initData()  }  doSomething(){    //触发事件  }  render(){    const{newsState,initData}=this.props    const{keyWord}=newsState    console.log(newsState)    return(      <div>        这里写子组件      </div>    )  }}export default NewsComponent

第四步就是写路由,即请求数据。我们在routes下创建news文件夹,并添加news_routes.js文件

router.post('/getInitData', function(req, res, next) {  var ops = {    url: `/news/getInitData`,    method: 'POST',    data: req.body    success: function(data) {      res.send(data);    }  }  restApi.request(req, ops);});

注意:还要配置路由

module.exports = {  routeConfig: function(app) {    //路由    app.use('/news', news) //页面路由  }}

reducer:

//使用redux的combineReducers方法将所有reducer打包起来const rootReducer = combineReducers({    newsState: newsReducer,})

大概的流程就是这样了

原创粉丝点击