uso usar react para método medium funciona estado español ejemplo componentes como javascript reactjs redux redux-thunk

javascript - usar - El estado de la tienda React/Redux no se guarda



redux-thunk (1)

Utilizo el middleware thunk y paso el estado inicial a Reaccionar, pero el problema es que el estado React no se guarda cuando visito otros enlaces.
Después de iniciar sesión con éxito, se supone que debe mostrar el tablero.
El usuario debe ser redirigido al panel (que es la ruta raíz, / ) cuando intenta ir a la página /login .

¿Debo usar redux-router también?

He omitido parte del código, pero casi se ve a continuación.

init.js
Pasé la tienda al Proveedor

import { Provider } from ''react-redux''; import configureStore from ''./store/configureStore''; const store = configureStore(); function requireAuth(nextState, replace) { const isLoggedIn = store.getState().auth.isLoggedIn; if (!isLoggedIn) { replace({ pathname: ''/login'', state: { nextPathname: nextState.location.pathname } }); } } <Provider store={store}> <Router history={browserHistory}> <Route path=''/'' component={App} store={store}> <IndexRoute components={{ main: MainServices, aside: Aside }} onEnter={requireAuth} /> <Route path="login" components={{ login: Login }} /> ... </Router> </Provider>

configureStore.js

import { createStore, applyMiddleware } from ''redux''; import thunk from ''redux-thunk''; import rootReducer from ''../reducers/index''; import initialState from ''./initialState''; const store = applyMiddleware(thunk)(createStore); export default function () { return store(rootReducer, initialState); }

initialState.js

var initialState = { auth: { isLoggedIn: false, isLoggingIn: false, response: null, }, }; export default initialState;

El estado de App.jsx Initial App se transfirió a los props de React

import React, { PropTypes } from ''react''; import { connect } from ''react-redux''; import Dashboard from ''./Dashboard''; import Login from ''./Login''; import { browserHistory } from ''react-router''; class App extends React.Component { constructor(props) { super(props); } render() { return ( <div className=''appWrapper height''> { this.props.auth.isLoggedIn ? <Dashboard {...this.props} /> : <Login {...this.props} /> } </div> ); } } let mapStateToProps = function(appState) { return { auth: appState.auth, }; }; let mapDispatchToProps = function(dispatch) { return { logoutRequest: function() { console.log("logoutRequest dispatched!"); } } }; export default connect(mapStateToProps, mapDispatchToProps)(App);

Login.jsx

export default class Login extends React.Component { constructor(props) { super(props); console.log(`componentWillMount in login`); if (this.props.auth.isLoggedIn) { console.log(`you already logged in..!`); browserHistory.push(''/''); } } render() { return ( <div className="login-outer"> <Grid className="login-inner"> <Row> <Col xs={12}> <LoginHeader /> <LoginContainer /> </Col> </Row> </Grid> </div> ); } }

LoginContainer.jsx

export default class LoginContainer extends React.Component { render() { return ( <div className="login-container"> <div className="outer"> <div className="inner"> <LoginTitle /> <div className="login-box"> <h2>Sign in</h2> <LoginInput /> </div> </div> </div> </div> ); } }

LoginInput.jsx

import React from ''react''; import { connect } from ''react-redux''; import { Input, ButtonToolbar, Button } from ''react-bootstrap''; import { spring } from ''react-motion''; import Transition from ''react-motion-ui-pack''; import Loader from ''react-loader''; import * as actions from ''../../actions/loginActions''; class LoginInput extends React.Component { constructor(props) { super(props); this.state = { idText: '''', passText: '''', idShow: false, passShow: false, loaded: true }; this.handleIdChange = this.handleIdChange.bind(this); this.handlePassChange = this.handlePassChange.bind(this); this.loginRequest = this.loginRequest.bind(this); } handleIdChange(e) { this.setState({ idText: e.target.value }); if (e.target.value != '''') { this.setState({ idShow: true }); } else { this.setState({ idShow: false }); } } handlePassChange(e) { this.setState({ passText: e.target.value }); if (e.target.value != '''') { this.setState({ passShow: true }); } else { this.setState({ passShow: false }); } } loginRequest(e) { this.setState({loaded: false}); if (!this.state.idText || !this.state.passText) { this.setState({loaded: true}); } if (this.state.idText && this.state.passText) { this.setState({ loaded: false, idText: this.state.idText, passText: this.state.passText, }); this.props.login(this.state.idText, this.state.passText); } e.preventDefault(); } render() { return ( <form className="loginForm"> <div className="form-group input-login id"> <input type="text" className="form-control" ref="idText" placeholder="ID" value={this.state.idText} onChange={this.handleIdChange} /> <Transition component={false} enter={{ opacity: 1 }} leave={{ opacity: 0 }} > { this.state.idShow && <label htmlFor="" className="control-label" > ID </label> } </Transition> </div> <div className="form-group input-login password"> <input type="password" className="form-control" ref="passText" placeholder="Password" value={this.state.passText} onChange={this.handlePassChange} /> <Transition component={false} enter={{ opacity: 1 }} leave={{ opacity: 0 }} > { this.state.passShow && <label htmlFor="" className="control-label" > Password </label> } </Transition> </div> <Input type="checkbox" groupClassName="checkbox-login" label="Keep me signed in" /> <ButtonToolbar> <Button href="#" onClick={this.loginRequest} > <div className="sign-arrow" hidden={!this.state.loaded} > <h6> ENTER </h6> <img src="images/ic-right-arrow-2.svg" alt="" /> </div> <Loader className="spinner" loaded={this.state.loaded} lines={10} length={3} width={2} radius={4} corners={1} rotate={0} direction={1} color="#fff" speed={1.5} trail={60} shadow={false} hwaccel={false} scale={1} /> </Button> </ButtonToolbar> </form> ); } } let mapStateToProps = function(appState) { return { auth: appState.auth, }; }; let mapDispatchToProps = function(dispatch) { return { login: function(id, pwd) { dispatch(actions.login(id, pwd)); } } }; export default connect(mapStateToProps,mapDispatchToProps)(LoginInput);

loginActions.js

export function loginFailure(error) { return { error, type: ActionTypes.LOGIN_FAILURE }; } export function loginSuccess(response) { return dispatch => { dispatch({ response, type: ActionTypes.LOGIN_SUCCESS }); browserHistory.push(''/''); }; } export function loginRequest(id, pwd) { return { type: ActionTypes.LOGIN_REQUEST, command: ''login'', lang: ''en'', str: encodeCredentials(id, pwd), ip: '''', device_id: '''', install_ver: '''', }; } export function login(id, pwd) { const credentials = loginRequest(id, pwd); return dispatch => { fetchJSON(`${API.ROOT_PATH}${API.END_POINT.LOGIN}`, { method: ''post'', body: credentials, }).then(data => { dispatch(loginSuccess(data)); }).catch(error => { console.log(`request failed ${error}`); }); }; }

reducrs / index.js

import authReducer from ''./authReducer''; import { combineReducers } from ''redux''; const rootReducer = combineReducers({ auth: authReducer, }); export default rootReducer;

authReducer.js

import initialState from ''../store/initialState''; import * as ActionTypes from ''../actionTypes/authActionTypes''; const authReducer = function authReducer(state = initialState.auth, action) { switch (action.type) { case ActionTypes.LOGIN_REQUEST: return Object.assign({}, state, { isLoggingIn: true, isLoggedIn: false, }); case ActionTypes.LOGOUT: return Object.assign({}, state, { isLoggedIn: false, isLoggingIn: false, }); case ActionTypes.LOGIN_FAILURE: return Object.assign({}, state, { error: action.error, isLoggingIn: false, isLoggedIn: false, }); case ActionTypes.LOGIN_SUCCESS: return Object.assign({}, state, { isLoggedIn: true, isLoggingIn: false, response: action.response, }); default: return state; } }; export default authReducer;


No hay forma de cómo su tienda se puede guardar entre dos solicitudes http diferentes. El único enfoque para eso no es recargar la página en sí, pero puedes emular para el usuario esa página se recargó cuando el usuario hace clic en el vínculo mediante la manipulación con la API de historial, que es un objeto nativo en todos los navegadores modernos. PERO el mejor enfoque es tomar reaccionar-enrutador que se encargará de todo lo que necesita en su aplicación reaccionar, y si desea mantener el estado del enrutador en su tienda redux puede usar redux-simple-router .