项目下载地址https://gitee.com/zhuangy/react-reduxjavascript
入口文件entry.js 建立storejava
import React from 'react'; import ReactDOM from 'react-dom'; import { createStore, applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; import { composeWithDevTools } from 'redux-devtools-extension'; import thunk from 'redux-thunk'; import { ConnectedRouter, routerReducer, routerMiddleware, push } from 'react-router-redux'; import { AppContainer } from 'react-hot-loader'; import App from './App'; import createHistory from 'history/createBrowserHistory'; import rootReducer from './reducers/index'; const history = createHistory(); const middleware = routerMiddleware(history) const middlewares = [thunk, middleware]; const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(...middlewares))); const render = Component => ReactDOM.render( <AppContainer> <Provider store={store}> <Component /> </Provider> </AppContainer>, document.getElementById('root') ); render(App) //模块热更新 if(module.hot) { module.hot.accept('./App', () => { render(App) }); }
路由App.jsreact
import React from 'react' import { connect } from 'react-redux' import { bindActionCreators } from 'redux'; import { Route, HashRouter as Router } from 'react-router-dom' import createHistory from 'history/createHashHistory' const history = createHistory() import HomeContainer from './containers/home/homeContainers' import Login from './containers/login/Login' import Register from './containers/register/register' export default class App extends React.Component { render() { return ( <Router history={history}> <Route render={({ location }) => { return( <div key={location.pathname}> <Route location={location} exact path="/" component={HomeContainer} /> <Route location={location} path="/login" component={Login} /> <Route location={location} path="/register" component={Register} /> </div> ) }}/> </Router> ); } }
路由组件主页F:homeContainers.jsgit
import React from 'react'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import Header from 'components/homeComponents/header'; import Hot from 'components/hot/hot'; export default class HomeContainer extends React.Component { constructor(props) { super(props); //构造函数用法 //经常使用来绑定自定义函数,不要在这里或者组件的任何位置setState,state所有在reducer初始化 } render() { alert(this.props.location); return( <div key={this.props.location}> <Header linkTo="login" linkToRegister="register" /> </div> ) } }
路由组件Login.js json
import React from 'react'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import * as login from 'actions/login'; import isEmpty from 'lodash/isEmpty'; / * dispatch用法:(单个action)bindActionCreators(navActions, dispatch),(多个action)bindActionCreators({...action1, ...action2}, dispatch) */ @connect ( state => state, dispatch => bindActionCreators(login, dispatch) ) export default class Login extends React.Component { constructor(props) { super(props); this.Click = (event) => { event.preventDefault(); let user = this.refs.user.value; let psw = this.refs.psw.value; if (isEmpty(user)) { alert('用户名为空'); } if (isEmpty(psw)) { alert('密码不能为空'); } this.props.login_success(user ,psw); } } render() { const {last_time} = this.props.login; return( <div> <form> <div> <span>用户名:</span> <input type='text' name='user' ref='user' placeholder='请输入用户名'/> </div> <div> <span>密码:</span> <input type='text' name='psw' placeholder='请输入密码' ref='psw'/> </div> <input type='submit' value='登录' onClick={this.Click} /> <div> {last_time} </div> </form> </div> ) } }
主页中的组件header.jsredux
import React ,{Component} from 'react'; import { Link } from 'react-router-dom'; class Header extends React.Component { render() { const { linkToRegister, linkTo } = this.props //传参数 return ( <div > <Link to={linkTo} className="login" >登录 </Link> <Link to={linkToRegister} className="register" >注册 </Link> </div> ) } } export default Header;
点击Link标签登录就会更加to的url跳转,Login组件,输入提交触发actionreact-router
actions----------login.jsapp
import fetch from 'isomorphic-fetch' import queryString from 'queryString' export const success = (data) => ({ type: 'login_success', data }) / // 页面初次渲染时获取数据 export const login_success = (user , psw) => { return dispatch => { fetch('http://localhost:9090/zl.zy/zy/login.do', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', }, body: queryString.stringify({ 'user': user ,'psw' :psw }) //用queryString转化,以前用JSON转化不行 }) .then((response) => { debugger if(response.ok){ return response.json(); } }) .then(data=> dispatch(success(data))) } } // 页面初次渲染时获取数据 export const login_success = (user , psw) => { return dispatch => { fetch('http://localhost:9090/zl.zy/zy/login.do', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', }, body: queryString.stringify({ 'user': user ,'psw' :psw }) //用queryString转化,以前用JSON转化不行 }) .then((response) => { debugger if(response.ok){ return response.json(); } }) .then(data=> dispatch(success(data))) } }
测试的时候后台没有搭建的话能够用 login.js,当提交成功的时候改变last_timedom
import fetch from 'isomorphic-fetch' export const login_success= () => ({ type: 'success', last_time:1 }) reducer: login.js const initState = { last_time:'2' } export const login = (state = initState, action) => { switch (action.type) { case "login_success": return { ...state, last_time: action.last_time, } default: return state } }
注册reducer:index.jside
import { combineReducers } from 'redux'; import { routerReducer } from 'react-router-redux' import { login } from './login'; //注册reducer,每一个自定义的reducer都要来这里注册!!!不注册会报错。 const rootReducer = combineReducers({ routing: routerReducer, login }); export default rootReducer;
最后将login.js中注册提交 last_time=1说明搭建成功