我正在开发一个使用redux-sagas和react-navigation v3的应用程序。
我现在面临的问题是我想在传奇中使用导航方法。该操作实际上已调度,我可以在记录器中看到它,但它不会更改我的屏幕。
这是我的文件:
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Provider } from 'react-redux';
import store from './store';
import Navigator from './routes/index.js'
export default function App() {
return (
<Provider store={store}>
<Navigator />
</Provider>
);
}
routes.js
import React from "react";
import { View, Text } from "react-native";
import {
createBottomTabNavigator,
createSwitchNavigator,
createStackNavigator,
createAppContainer
} from "react-navigation";
import { FontAwesome } from '@expo/vector-icons';
// Screens
import LoginScreen from '../screens/Login.js';
// Routes
import Leads from './leads.js';
import Settings from './settings.js';
const TabsStack = createBottomTabNavigator(
{
Leads: Leads ,
Settings: Settings,
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
const iconSize = 28;
let iconName;
if (routeName === 'Leads') {
iconName = 'home'
} else if(routeName === 'Settings'){
iconName = 'cogs'
}
return <FontAwesome name={iconName} size={iconSize} color={tintColor} />
},
}),
tabBarOptions: {
activeTintColor: '#208DFF',
inactiveTintColor: '#cecece',
showLabel: false
},
}
);
const LoginStack = createStackNavigator({
Login: {
screen: LoginScreen,
navigationOptions: ({navigation}) => ({
header: null
})
}
});
const Router = createSwitchNavigator(
{
Login: LoginStack,
Tabs: TabsStack,
},
{
initialRouteName: "Login"
}
);
export default createAppContainer(Router);
store.js
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from "redux-saga";
import { createLogger } from 'redux-logger';
import sagas from '../sagas/';
import reducers from '../reducers/';
const sagaMiddleware = createSagaMiddleware();
const loggerMiddleware = createLogger({collapsed: true});
const store = createStore(
reducers,
applyMiddleware(sagaMiddleware, loggerMiddleware)
);
sagaMiddleware.run(sagas);
export default store;
最后是我的传奇
import { takeLatest, call, put } from "redux-saga/effects";
import { NavigationActions } from "react-navigation";
import * as sessionActions from '../actions/sessions';
import * as navigateActions from '../actions/navigation.js';
import { login } from '../api/index.js';
import { AsyncStorage } from 'react-native';
export function* loginRequest({email, password}){
let response = yield call(login, {email, password})
if(!response.error){
saveToken(response.auth_token);
yield put({type: sessionActions.SESSION_LOGIN_REQUEST_SUCCESS, user: response})
}else{
yield put({type: sessionActions.SESSION_LOGIN_REQUEST_FAILURE, error: response.error})
}
}
export function* loginRequestSuccessful(){
console.log("Teste! 2");
yield put(NavigationActions.navigate({ routeName: 'Leads' }))
}
async function saveToken(token) {
try {
return await AsyncStorage.setItem("auth_token", token);
} catch (err) {
console.error(err);
}
}
function* loginSaga(){
yield takeLatest(sessionActions.SESSION_LOGIN_REQUEST, loginRequest);
yield takeLatest(sessionActions.SESSION_LOGIN_REQUEST_SUCCESS, loginRequestSuccessful);
}
export default loginSaga;
我是从记录器那里得到的
action Navigation/NAVIGATE @ 20:23:07.668
RemoteConsole.js:80 prev state {sessions: {…}}
RemoteConsole.js:80 action {type: "Navigation/NAVIGATE", routeName: "Leads", @@redux-saga/SAGA_ACTION: true}
RemoteConsole.js:80 next state {sessions: {…}}
我不知道如何导航到sagas函数中的另一个屏幕。
导航工作的唯一方法是在组件内部使用this.props.navigation,但我需要在sagas内部进行工作。
答案 0 :(得分:1)
在我的项目中,我按如下操作:
AppContainer = createAppContainer(this.Switch);
constructor(props: any) {
super(props);
this.state = {};
}
handleNavigationChange = (
prevState: NavigationState,
newState: NavigationState,
action: NavigationAction,
) => {
};
render(): React.ReactNode {
return (
<Root>
{/* <StatusBar barStyle="dark-content" /> */}
<this.AppContainer
ref={(navigatorRef: any) => {
serviceProvider.NavigatorService().setContainer(navigatorRef);
}}
onNavigationStateChange={this.handleNavigationChange}
/>
</Root>
);
}
import { NavigationActions, NavigationParams, NavigationRoute, NavigationContainerComponent, NavigationContainer } from 'react-navigation';
export default class NavigatorService {
container?: NavigationContainerComponent & NavigationContainer;
setContainer = (container: NavigationContainerComponent & NavigationContainer): void => {
this.container = container;
}
getContainer = (container: NavigationContainerComponent & NavigationContainer): any => {
return container;
}
navigate = (routeName: string, params?: NavigationParams): void => {
if (this.container) {
this.container.dispatch(
NavigationActions.navigate({
routeName,
params,
}),
);
}
}
goBack = (): void => {
if (this.container) {
this.container.dispatch(
NavigationActions.back(),
);
}
}
getCurrentRoute(): NavigationRoute | null {
if (!this.container || !this.container.state.nav) {
return null;
}
return this.container.state.nav.routes[this.container.state.nav.index] || null;
}
}
serviceProvider.NavigatorService().navigate(//screenName)