我必须在登录后将用户重定向到应用程序的主要组件。我使用redux来管理状态。
我尝试从this thread:
更改我的登录方法import axios from 'axios'
import { push } from 'react-router-redux'
import { API_URL } from '../utils/apiUrl'
export const loginUser = creds => {
return dispatch => {
dispatch(loginRequest(creds))
axios({
method: "post",
url: API_URL + "/auth_token",
data: { auth: creds }
}).then(res => {
dispatch(push('/home')) /* dispatch an action that changes the browser history */
})
}).catch(err =>
dispatch(loginFailure('Wrong email/password combination'))
)
}
}
所以在我的情况下它看起来像这样:
export function authenticate(user, password) {
var data = {
"username" : user,
"password": password
};
return function(dispatch) {
return axios({
url: 'someserver:xxxx/login',
timeout: 20000,
method: 'POST',
data: data,
}).then(function(response) {
dispatch(loggedIn(response.data.token));
}).then(res => {
dispatch(push('/main')); <------ route to main page
}).catch(function(error) {
if (error.response) {
// DEBUGGING
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
})
}
}
const loggedIn = (token) => ({
type: "LOGIN",
token
})
App.js看起来像这样:
render() {
return (
<Router>
<div style={{textAlign : 'center'}}>
<Route path="/main" component={Main}/>
<img src={Logo} alt="fireSpot"/>
<p style={{paddingTop: '2%'}}>LOGIN</p>
<form>
<TextField
id="username"
label="USERNAME"
value={this.state.username}
onChange={(event) => this.handleUsername(event)}
margin="normal"
/> <br />
<TextField
value={this.state.password}
onChange={(event) => this.handlePassword(event)}
id="password"
label="PASSWORD"
type="password"
autoComplete="current-password"
margin="normal"
/>
<br />
<MuiThemeProvider theme={theme}>
<Button
onClick={
this.handleSubmit
}
disabled={!this.validateForm()}
type="submit"
variant="raised"
color="secondary"
>
Anmelden
</Button>
</MuiThemeProvider>
</form>
</div>
</Router>
);
}
}
handleSubmit
方法:
handleSubmit = (event) => {
event.preventDefault();
this.props.login();
}
mapDispatchToProps
:
const mapDispatchToProps = (dispatch) => {
return {
login : function() {
dispatch(authenticate(this.state.username, this.state.password));
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
登录有效。我甚至可以打印出我得到的回复:{type: "@@router/CALL_HISTORY_METHOD", payload: {…}}
,但没有任何反应。
有什么想法吗?
修改
与此同时,我加入了App.js
handleSubmit = async (event) => {
event.preventDefault();
await this.props.login();
this.props.history.push('/main')
}
并使用withRouter
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
我将ReactDOM.render(<App store={store}/>...
行更改为
ReactDOM.render(<Router><div><App store={store} /> </div></Router>, document.getElementById('root'));
摆脱了A <Router> may have only one child element
错误。现在它似乎重定向到某个地方,但它最终会出现在:
Could not find "store" in either the context or props of "Connect(Main)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Main)".
编辑2:
我导入了提供商并将store
作为props
传递给它,现在它可以正常工作。
ReactDOM.render(
<Provider store={store}>
<Router>
<div>
<App store={store} />
</div>
</Router>
</Provider>, document.getElementById('root'));
现在只发布,它只是在登录字段中添加Main
的内容。有什么想法吗?
编辑3:
我从Router
删除了与App.js
相关的所有内容,然后像这样编辑了index.js
文件。
<Provider store={store}>
<Router>
<div>
<Route exact path="/" component={App}/>
<Route path="/main" component={Main}/>
</div>
</Router>
</Provider>, document.getElementById('root'));
它在登录后解决了堆叠组件问题。我不知道如何从login
返回一些内容,以便在凭据确认时应用程序不会前进到Main
错误,正如@ ivica.moke在评论中写道的那样。
答案 0 :(得分:1)
登录异步,并等待登录响应,然后在该过程完成后推送到&#39; / main&#39;。您甚至可以从login()操作返回一些内容,并根据响应甚至推送到main(如果成功)或强制输入有效凭据(如果未成功登录)。
handleSubmit =async (event) => {
event.preventDefault();
await this.props.login();
this.props.history.push('/main');
}
修改强>
在使用axios
的API调用中,您的服务器有望返回一些状态代码。来自.then
的{{1}}内部,您可以在其中收到axios
,您可以检查该状态代码(请参阅console.log(res))以查看您的API返回的内容。然后只从res
返回.then
或res
。
res.status
在handleSubmit内部
axios.post(url,data)
.then(res => {
// here you check status code from API response
// and return response or it's status code
return res;
})
.catch(error => {
//if error meaning not statusCode 200 (login failed for some reason)
return error;
});
我希望这会让它更清晰。