我知道之前已经问过这个问题,但理想情况下我想保持导航状态存储在react navigation而不是redux中,我最近从React-Native-Router-Flux迁移,我能够调用导航redux动作中的动作本身不像react-navigation
loginUser操作
export const loginUser = ({ email, password }) => {
return dispatch => {
dispatch({ type: LOGIN_USER });
return AuthApi.login(email, password)
.then(response => {
return response.json();
})
.then(result => {
if (result.ok) {
// authenticated successfully
dispatch(setLoginSuccess(result.auth_token));
_saveItem("authToken", result.auth_token);
} else {
dispatch(setLoginFail(result.message));
}
});
};
};
成功验证后有没有办法调用this.props.navigation.navigate('Home')
?
导航
const AppStack = createStackNavigator(
{
Home: {
screen: BottomTabNavigator,
navigationOptions: {
header: null
}
},
Profile: {
screen: ProfileScreen,
navigationOptions: {
header: null
}
},
Quest: {
screen: QuestScreen,
navigationOptions: ({ navigation }) => ({
title: "Quest Info",
headerLeft: (
<HeaderBackButton
tintColor={"#FFF"}
onPress={() => navigation.navigate("Home")}
/>
),
headerStyle: {
backgroundColor: "#E8536D",
borderBottomColor: "transparent",
borderBottomWidth: 0,
elevation: 0,
shadowOpacity: 0
},
headerTitleStyle: {
fontWeight: "bold",
color: "#FFF"
}
})
},
Test: {
screen: TestScreen,
navigationOptions: {
header: null
}
}
},
{
initialRouteName: "Home"
}
);
const AuthStack = createStackNavigator(
{
Tutorial: {
screen: TutorialScreen,
navigationOptions: {
header: null
}
},
Login: {
screen: LoginScreen,
navigationOptions: {
header: null
}
},
Register: {
screen: RegisterScreen,
navigationOptions: ({ navigation }) => ({
title: "Sign Up With Email",
headerLeft: (
<HeaderBackButton
tintColor={"#FFF"}
onPress={() => navigation.navigate("Login")}
/>
),
headerStyle: {
backgroundColor: "#E8536D",
borderBottomColor: "transparent",
borderBottomWidth: 0,
elevation: 0,
shadowOpacity: 0
},
headerTitleStyle: {
fontWeight: "bold",
color: "#FFF"
}
})
},
ResetPassword: {
screen: ResetPasswordScreen,
navigationOptions: ({ navigation }) => ({
title: "Reset Your Password",
headerLeft: (
<HeaderBackButton
tintColor={"#FFF"}
onPress={() => navigation.navigate("Login")}
/>
),
headerStyle: {
backgroundColor: "#E8536D",
borderBottomColor: "transparent",
borderBottomWidth: 0,
elevation: 0,
shadowOpacity: 0
},
headerTitleStyle: {
fontWeight: "bold",
color: "#FFF"
}
})
}
},
{
initialRouteName: "Tutorial"
}
);
export default (RootNavigator = () => {
return createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack
},
{
initialRouteName: "Auth"
}
);
});
Auth Reducer
import {
EMAIL_CHANGED,
PASSWORD_CHANGED,
LOGIN_USER,
LOGIN_USER_SUCCESS,
LOGIN_USER_FAIL,
SIGNUP_USER,
SIGNUP_SUCCESS,
SIGNUP_FAIL
} from "../actions/types";
const INITIAL_STATE = {
email: "",
password: "",
user: null,
error: "",
isAuthenticated: false,
loading: false,
Authorization: null
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case EMAIL_CHANGED:
// returns a new state with ...state by creating a new object
return { ...state, error: "", email: action.payload };
case PASSWORD_CHANGED:
return { ...state, error: "", password: action.payload };
case LOGIN_USER:
return { ...state, loading: true, error: "" };
case LOGIN_USER_SUCCESS:
return {
...state,
email: "",
password: "",
loading: false,
isAuthenticated: true,
error: "",
Authorization: action.payload
};
case LOGIN_USER_FAIL:
return {
...state,
email: "",
password: "",
loading: false,
error: action.payload
};
case SIGNUP_USER:
return { ...state, loading: true, error: "" };
case SIGNUP_SUCCESS:
return {
...state,
email: "",
password: "",
loading: false,
isAuthenticated: true,
Authorization: action.payload,
error: ""
};
case SIGNUP_FAIL:
return {
...state,
email: "",
password: "",
loading: false,
error: action.payload
};
default:
return state;
}
};
LoginScreen
loginUser = () => {
const { email, password } = this.props;
this.props.loginUser(
{ email, password },
);
};
componentDidUpdate() {
if(this.props.isAuthenticated === true) {
this.props.navigation.navigate('Home');
}
};
const mapStateToProps = ({ auth }) => {
const { email, password, error, loading, isAuthenticated } = auth;
return { email, password, error, loading, isAuthenticated };
};
export default connect(
mapStateToProps,
{
emailChanged,
passwordChanged,
loginUser
}
)(LoginScreen);
答案 0 :(得分:2)
是的,我可以使用与您在此处完全相同的方法:带有LoadingScreen,AuthStack和AppStack的SwichtNavigator。
您只需要通过react-redux的connect helper将RegisterScreen连接到redux商店,并使用mapStateToProps挂钩商店的一部分,一旦用户通过屏幕道具验证,将会更新。然后你只需使用componentDidUpdate(),如下所示:
class RegisterScreen extends React.Component {
...
public componentDidUpdate(): void {
if (this.props.isAuthenticated === true) {
this.props.navigation.navigate('Home');
}
}
}
const mapStateToProps = (state) => {
return {
isAuthenticated: state.isAuthenticated // or whatever your state property is called
};
};
export default connect(mapStateToProps)(RegisterScreen);