我想在触发操作后重定向客户端。我听说过react-redux-router
,但不确定如何在动作函数中正确实现它。
我遵循了这一点
https://stackoverflow.com/a/42985875/10865515
但是,当我提交经过验证的表单时,它不会重定向或刷新。
Actions.js
import { auth as firebaseAuth } from '../firebaseConfig'
import { push, browserHistory } from 'react-router-redux';
export const signUp = (user) => { return (dispatch) => {
firebaseAuth.createUserWithEmailAndPassword(user.email, user.password)
.then(() => {
dispatch({ type: 'SIGNUP_SUCCESS',
payload: (action, state, res) => {
return res.json().then(json => {
browserHistory.push('/');
return json;
});
},
});
}).catch((err) => {
dispatch({ type: 'SIGNUP_ERROR', err});
});
}
}
Reducers.js
const initialState = {
emailSignUp: '',
passwordSignUp: '',
authError: null
}
export default (state = initialState, action) => {
switch (action.type) {
case 'SIGNUP_SUCCESS':
return ({
...state,
authError: null
})
case 'SIGNUP_ERROR':
console.log('signup error')
return ({
...state,
authError: action.err.message
})
default:
return state
}
}
Register.js
// ...
handleSubmit(event) {
event.preventDefault();
const {formData, errors} = this.state;
const {email, password} = formData;
const myError = this.props.authError;
const creds = {
email,
password
}
const register = this.props.signUp(creds);
if (register) {
console.log(creds);
}
}
答案 0 :(得分:1)
您应该实现react-router-dom
库,该库使您可以访问history
对象进行导航。
在触发动作创建者的组件中:
import { withRouter } from "react-router-dom"
然后在代码底部,您将其称为connect:
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(myComponent))
现在,您可以将动作创建者设置为以历史为依据。
您的操作文件:
const signUp = (creds, history) => {
//do some logic then go home
history.push("/")
}
因此,在您的事件处理程序中(您将其称为动作创建者),传递历史记录:
handleSubmit(event) {
event.preventDefault();
this.props.signUp(creds, this.props.history);
if (register) {
console.log(creds);
}
}
答案 1 :(得分:0)
这是我关于firebase和redux的示例:
在您的动作内部,创建用户并将适当的动作分配给减速器:
export const signUp = newUser => {
return (dispatch, getState, { getFirebase, getFirestore }) => {
const firebase = getFirebase();
const firestore = getFirestore();
firebase
.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then(resp => {
return firestore
.collection('users')
.doc(resp.user.uid)
.set({
firstName: newUser.firstName,
lastName: newUser.lastName
});
})
.then(() => {
dispatch({ type: 'SIGNUP_SUCCESS' });
})
.catch(err => {
dispatch({ type: 'SIGNUP_ERROR', err });
});
};
};
在您的减速器中,您可以处理状态更改:
case 'SIGNUP_SUCCESS':
return {
...state,
authError: null
};
case 'SIGNUP_ERROR':
return {
...state,
authError: action.err.message
};
在组件中,您从Redirect
导入react-router-dom
并在成功注册后重定向:
import { Redirect } from 'react-router-dom';
class SignIn extends Component {
state = {
email: '',
password: ''
};
handleChange = e => {
this.setState({
[e.target.id]: e.target.value
});
};
handleSubmit = e => {
e.preventDefault();
this.props.signIn(this.state);
};
render() {
const { authError, auth } = this.props;
if (auth.uid) return <Redirect to="/" />;
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
...
</form>
</div>
);
}
}
const mapStateToProps = state => {
return {
authError: state.auth.authError,
auth: state.firebase.auth
};
};
const mapDispatchToProps = dispatch => {
return {
signIn: creds => dispatch(signIn(creds))
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(SignIn);
答案 2 :(得分:0)
我修复了。
部分问题源自此
React history.push() is updating url but not navigating to it in browser
并且不知道如何正确使用then
我需要在应用程序周围包裹路由器标签
import App from './App';
import * as serviceWorker from './serviceWorker';
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux';
import rootReducer from './reducers';
import thunk from 'redux-thunk'
import { BrowserRouter as Router } from 'react-router-dom';
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(rootReducer)}>
<Router >
<App />
</Router>
</Provider>
,document.getElementById('root'));
并像这样更新我的动作
import { push } from 'react-router-redux';
import { history } from '../components/Navbar';
export const signUp = (user) => { return (dispatch) => {
firebaseAuth.createUserWithEmailAndPassword(user.email, user.password)
.then(() => {
dispatch({ type: 'SIGNUP_SUCCESS' })
}).then((response) => {
history.push('/');
}).catch((err) => {
dispatch({ type: 'SIGNUP_ERROR', err});
});
}
}
Navbar.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import createBrowserHistory from 'history/createBrowserHistory';
import SignUp from './SignUp';
import SignIn from './SignIn';
// forcerefresh does the magic.
export const history = createBrowserHistory({forceRefresh:true});
const Navbar = () => {
return(
<Router history={history}>
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-light ">
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample08" aria-controls="navbarsExample08" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse justify-content-md-center" id="navbarsExample08">
<ul className="navbar-nav">
<li className="nav-item">
<Link className="nav-link" to="/">Home </Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/SignUp">Sign Up </Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/SignIn">Sign In </Link>
</li>
</ul>
</div>
</nav>
<Route path="/SignUp" component={SignUp} />
<Route path="/SignIn" component={SignIn} />
<Route path="/"/>
</div>
</Router>
);
}
export default Navbar;
保持现有的handleSubmit函数不变。