我在react native中遇到了这个问题,但它在react dom中起作用。 另外,除了反应导航中间件,我没有使用中间件,反应导航中间件是集成到redux中的。 我要执行的操作是发送电话和密码以进行操作,该操作将提取令牌并保存到redux存储,之后我也想检索它以进行令牌身份验证
商店
import React from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import AppReducer from './src/reducers';
import { AppNavigator, middleware } from './src/navigators';
const store = createStore(AppReducer, applyMiddleware(middleware));
class App extends React.Component {
render() {
return (
<Provider store={store}>
<AppNavigator />
</Provider>
);
}
}
export default App;
操作
export const login = (phone, password) => {
return (dispatch, getState) => {
let headers = { 'Content-Type': 'application/json' };
let body = JSON.stringify({ phone, password });
return fetch('/api/auth/login/', { headers, body, method: 'POST' })
.then(res => {
if (res.status < 500) {
return res.json().then(data => {
return { status: res.status, data };
});
} else {
console.log('Server Error!');
throw res;
}
})
.then(res => {
if (res.status === 200) {
dispatch({ type: 'LOGIN_SUCCESSFUL', data: res.data });
return res.data;
} else if (res.status === 403 || res.status === 401) {
dispatch({ type: 'AUTHENTICATION_ERROR', data: res.data });
throw res.data;
} else {
dispatch({ type: 'LOGIN_FAILED', data: res.data });
throw res.data;
}
});
};
};
减速器
import { combineReducers } from 'redux';
import { NavigationActions } from 'react-navigation';
import { RootNavigator } from '../navigators';
// Start with two routes: The Main screen, with the Login screen on top.
const firstAction = RootNavigator.router.getActionForPathAndParams('Main');
const tempNavState = RootNavigator.router.getStateForAction(firstAction);
const secondAction = RootNavigator.router.getActionForPathAndParams('Login');
const initialNavState = RootNavigator.router.getStateForAction(
secondAction,
tempNavState
);
function nav(state = initialNavState, action) {
let nextState;
switch (action.type) {
case 'Login':
nextState = RootNavigator.router.getStateForAction(
NavigationActions.back(),
state
);
break;
case 'Logout':
nextState = RootNavigator.router.getStateForAction(
NavigationActions.navigate({ routeName: 'Login' }),
state
);
break;
default:
nextState = RootNavigator.router.getStateForAction(action, state);
break;
}
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state;
}
const initialAuthState = {
token: null,
isAuthenticated: null,
isLoading: true,
user: null,
errors: {}
};
function auth(state = initialAuthState, action) {
switch (action.type) {
case 'USER_LOADING':
return { ...state, isLoading: true };
case 'USER_LOADED':
return {
...state,
isAuthenticated: true,
isLoading: false,
user: action.user
};
case 'LOGIN_SUCCESSFUL':
case 'REGISTRATION_SUCCESSFUL':
return {
...state,
token: action.token,
...action.data,
isAuthenticated: true,
isLoading: false,
errors: null
};
case 'AUTHENTICATION_ERROR':
case 'LOGIN_FAILED':
case 'REGISTRATION_FAILED':
case 'LOGOUT_SUCCESSFUL':
return {
...state,
errors: action.data,
token: null,
user: null,
isAuthenticated: false,
isLoading: false
};
case 'Login':
return { ...state, isLoggedIn: true };
case 'Logout':
return { ...state, isLoggedIn: false };
default:
return state;
}
}
const AppReducer = combineReducers({
nav,
auth
});
export default AppReducer;
登录页面
import React, { Component } from 'react';
import { Button, StyleSheet, Text, View, TextInput } from 'react-native';
import { connect } from 'react-redux';
import { login } from '../actions/auth';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10
}
});
class LoginPage extends Component {
state = {
phone: '',
password: ''
};
render() {
console.log(this.state.phone);
return (
<View style={styles.container}>
<TextInput
style={{ height: 40, width: 100 }}
placeholder="Enter phone number"
onChangeText={text => this.setState({ phone: text })}
value={this.state.phone}
/>
<TextInput
style={{ height: 40, width: 100 }}
placeholder="Enter passoword"
onChangeText={text => this.setState({ password: text })}
value={this.state.password}
/>
{this.props.errors.length > 0 &&
this.props.errors.map(error => (
<Text key={error.field}>{error.message}</Text>
))}
<Button
onPress={() =>
this.props.login(this.state.phone, this.state.password)
}
title="Log in"
/>
</View>
);
}
}
LoginPage.navigationOptions = {
title: 'Log In'
};
const mapStateToProps = state => {
let errors = [];
if (state.auth.errors) {
errors = Object.keys(state.auth.errors).map(field => {
return { field, message: state.auth.errors[field] };
});
}
return {
errors,
isAuthenticated: state.auth.isAuthenticated
};
};
// const mapDispatchToProps = dispatch => {
// return {
// login: (phone, password) => {
// return dispatch(auth.login(phone, password));
// }
// };
// };
const mapDispatchToProps = {
login
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(LoginPage);
答案 0 :(得分:0)
所以我认为问题在于您没有使用任何Redux中间件,这些中间件都可以使您编写返回函数的动作创建器。
现在,如果您不使用redux中间件,则只能返回这样的操作
ERROR in ./src/app/menu/transaction/result/result.component.scss
(Emitted value instead of an instance of Error) CssSyntaxError: C:\TeamProjects\Web\Dev\Portal\node_modules\@swimlane\ngx-datatable\release\assets\icons.css:9:4: Can't resolve 'fonts/data-table.svg' in 'C:\Projects\Web\Dev\Portal\src\app\menu\transaction\result'
尝试Redux-thunk库。
for (_, value) in json["assets"] {
for item in value.arrayValue {
let url = item["urlImage"].stringValue
print(url)
}
}
现在,在您的applyMiddleware函数中,我认为您可以将redux-thunk中间件以及当前的中间件放入其中。
放置后,我认为它不再会引发错误。
让我知道怎么回事。