項目下載地址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說明搭建成功