我是Redux的新手,似乎有问题。一旦调度了我的操作,该操作就成功了,但是父组件直到进行另一个状态更改后才获得更新的状态。如果单击登录,然后在输入字段中删除一个字符,则会触发状态更改,向我显示菜单。非常感谢任何帮助/指针,谢谢。
主要(父母):
import React, { Component } from 'react'
import { connect } from 'react-redux'
import Login from '../login'
import Menu from '../menu'
type Props = { token: string }
class Main extends Component<Props, {}> {
render() {
const { token } = this.props;
if (!token) {
return (
<Login />
)
}
return (
<Menu />
)
}
}
const mapStateToProps = (state) => ({
token: state.session.token,
})
export default connect(
mapStateToProps,
null,
)(Main)
登录(儿童):
import React from 'react'
import { connect } from 'react-redux'
import { login } from '../../redux/session/session.actions'
import { View, StyleSheet } from 'react-native'
import { Button, FormLabel, FormInput, FormValidationMessage } from 'react-native-elements'
import styled from 'styled-components/native'
const Container = styled(View)`
flex: 1;
flex-direction: column;
justify-content: center;
align-items: center;
`
const Wrapper = styled(View)`
width: 300;
`
type Props = { login: Function, error: string, loading: boolean };
type State = { email: string, password: string };
class Login extends React.PureComponent<Props, State> {
constructor(props) {
super(props);
this.state = {
email: null,
password: null,
}
}
render() {
console.log('props', this.props);
console.log('state', this.state);
const { loading, error } = this.props;
return (
<Container>
<Wrapper>
<FormValidationMessage>{loading ? 'Loading...' : null}</FormValidationMessage>
<FormValidationMessage>{error ? 'Unable to login, please try again.' : null}</FormValidationMessage>
<FormLabel>Email:</FormLabel>
<FormInput onChangeText={text => this.setState({ email: text })} />
<FormLabel>Password:</FormLabel>
<FormInput secureTextEntry onChangeText={password => this.setState({ password })} />
<Button title='Login' onPress={this.login} />
</Wrapper>
</Container>
)
}
login = () => {
this.props.login(this.state.email, this.state.password);
}
}
const mapStateToProps = (state) => {
console.log(state);
return {
error: state.session.error,
loading: state.session.loading
}
}
const mapDispatchToProps = ({
login
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Login);
减速器:
import {
LOGGING_IN,
LOGIN_SUCCESS,
LOGIN_FAILED
} from './session.types'
const initialState = {
loading: null,
error: null,
token: null,
}
export default (state = initialState, { type, payload }) => {
switch (type) {
case LOGGING_IN:
return {
...state,
loading: true
}
case LOGIN_SUCCESS:
return {
...state,
loading: false,
error: null,
token: payload.token
}
case LOGIN_FAILED:
return {
...state,
loading: false,
error: payload.error
}
default:
return state
}
}
操作:
import { API_URL } from '../../../app-env'
import axios from 'axios'
import {
LOGGING_IN,
LOGIN_SUCCESS,
LOGIN_FAILED
} from './session.types'
export const login = (email, password) => (
async dispatch => {
console.log('here');
dispatch(loggingIn());
await axios.post(`${API_URL}/login`, {
email,
password
}).then(res => {
dispatch(loginSuccess(res.data.token))
}).catch(err => {
dispatch(loginFailed('Unable to login.'))
})
}
)
export const loggingIn = () => ({
type: LOGGING_IN,
})
export const loginSuccess = (token) => ({
type: LOGIN_SUCCESS,
payload: {
token
}
})
export const loginFailed = (error) => ({
type: LOGIN_FAILED,
payload: {
error
}
})
答案 0 :(得分:0)
由于您的问题是有关Menu
无法渲染并且Menu
在Main
下。因此,我们可以问一个问题,Main
组件不重新呈现。幸运的是,您的示例Main
仅取决于一个道具,而没有任何状态。 -我会说您的问题出在props.token上。-由于您将令牌初始化为null
,因此我假设它具有对象类型。在这种情况下,您需要确保令牌需要是一个新对象(新引用),否则不能重新渲染,因为默认情况下,react-redux connect
将在触发其下方的组件之前检查道具更改。 / p>
编辑:您提到Menu
未显示且令牌为字符串,我可以想到另一个未渲染Main
的原因是因为connect
未触发。您可能需要检查存储的根目录,并确保它具有新的引用,因为您的代码仅显示了reducer更新state.session,而不显示状态本身。