我有一个用户可以登录的用例。一旦用户登录,就应该显示另一个组件。这对我不起作用。我必须再次点击登录按钮来显示另一个组件,或者刷新页面。
以下是我所做的
这是父组件
const mapStateToProps = state => {
return {
user: state.loginReducer
}
}
class App extends React.Component {
state = {
hasToken: false
}
componentDidMount() {
const { user } = this.props;
window.chrome.storage.sync.get(['user_token'], result => {
if ((user && user.access_token) || result.user_token) {
console.log('user_token in cdm', result, user);
this.setState({ hasToken: true })
}
})
}
componentWillReceiveProps(nextProps) {
if (this.props.user !== nextProps.user) {
window.chrome.storage.sync.get(['user_token'], result => {
if (nextProps.user.length || result.user_token) {
this.setState({ hasToken: true })
}
})
}
}
anotherComponent() { // just to show the demo
return (
<div class="content">
component to show when the user logs in
</div>
)
}
render() {
const { hasToken } = this.state;
return (
<div>
<Header />
{ !hasToken ? <Login /> : this.anotherComponent()}
</div>
)
}
}
export default connect(mapStateToProps, null)(App);login.js
const mapDispatchToProps = dispatch => ({
userLogin: user => dispatch(login(user))
})
class Login extends React.Component {
state = {
user: {
email:"",
password: "",
grant_type: "password"
}
}
handleChange = e => {
this.setState({user: {...this.state.user, [e.target.name]: e.target.value}})
}
handleSubmit = e => {
e.preventDefault();
this.props.userLogin(this.state.user);
}
render() {
const { user } = this.state;
return (
<Grid>
<Row className="pad-10">
<Col sm={12} md={6} mdOffset={3}>
<Form onSubmit={this.handleSubmit}>
<FormGroup controlId="email">
<ControlLabel>Email</ControlLabel>
<FormControl
type="email"
placeholder="Email"
name="email"
onChange={this.handleChange}
value={user.email}
/>
</FormGroup>
<FormGroup controlId="password">
<ControlLabel>Password</ControlLabel>
<FormControl
type="password"
placeholder="Password"
name="password"
onChange={this.handleChange}
value={user.password}
/>
</FormGroup>
<FormGroup>
<Button type="submit">Sign in</Button>
</FormGroup>
</Form>
</Col>
</Row>
</Grid>
);
}
}
export default connect(null, mapDispatchToProps)(Login);我没有使用任何路由器概念,所以我想做的是,当用户点击登录按钮,如果登录成功,令牌将从服务器响应,并检查,以便如果它是成功的,用户将显示另一个组件。
更新
export const login = action(LOGIN, 'user');
export const loginSuccess = action(LOGIN_SUCCESS, 'data');
export const loginFailure = action(LOGIN_FAILURE, 'error');减速器码
const initialState = {
fetching: false,
error: null,
user: []
}
function loginReducer(state=initialState, action) {
switch (action.type) {
case LOGIN:
return {...state, fetching: true}
case LOGIN_SUCCESS:
return {...state, fetching: false, user: action.data.access_token}
case LOGIN_FAILURE:
return {...state, fetching: false, error: action.error}
default:
return state;
}
}
export default loginReducer;发布于 2018-05-15 05:11:06
我不知道window.chrome.storage.sync到底是如何工作的,但显而易见的解决方案(乍一看)是:
// parent component
render() {
const { user } = this.props;
return (
<div>
<Header />
{ !user ? <Login /> : this.anotherComponent()}
</div>
)
}你必须从你的状态得到用户我会提供更多的细节当你带着你的减速器/动作
发布于 2018-05-15 05:14:15
您的代码不起作用的问题是,不管用户是否登录,App组件只呈现一次。因此,稍后当用户登录时,您的应用程序组件将不会重新呈现。
有很多方法可以解决这个问题。我建议您这样做:将一个onUserLogin回调传递给组件,比如
<LoginModal isModalOpen={isModalOpen} onLoginClick={this.onLoginClick} />然后在setState函数中执行onLoginClick,以确保组件是用更改的道具呈现的。
onLoginClick = () => {
if (!this.state.isUserLoggedIn) {
this.setState({
isModalOpen:!this.state.isModalOpen,
});
}
}https://stackoverflow.com/questions/50342646
复制相似问题