代码之家  ›  专栏  ›  技术社区  ›  500 Server error

redux坚持不使用react本机应用程序

  •  0
  • 500 Server error  · 技术社区  · 7 年前

    问题

    预期行为

    该应用程序基本上只有一个登录表单,其中会触发一些redux操作。例如,用户名和密码都保存到存储中。

    在使用Reactotron进行检查之后,存储实际上按照预期进行了改进,用户名和密码以及其他字段都会更新。

    技术堆栈

    使用Redux响应本机应用程序(非Expo)

    package.json

    "dependencies": {
        "react": "16.6.1",
        "react-native": "0.57.7",
        "react-native-gesture-handler": "^1.0.12",
        "react-native-i18n": "^2.0.15",
        "react-navigation": "^3.0.8",
        "react-redux": "^6.0.0",
        "redux": "^4.0.1",
        "redux-persist": "^5.10.0"
      },
    

    应用状况

    App.js

    import React, {Component} from 'react';
    import { Provider } from 'react-redux';
    import LoadingIndicator from '@components/Visual/LoadingIndicator/';
    import MainNavigator from '@components/Visual/MainNavigator'
    import {checkUserState} from '@actions/GlobalActions'
    import {store, persistor} from '@components/Storage/StorageConfigurationBuilder'
    import { PersistGate } from 'redux-persist/integration/react'
    
    export default class App extends Component {
      constructor(props) {
        super(props);
      }
    
      componentDidMount() {
        store.dispatch(checkUserState())
      }
    
      render() {
        return (
            <Provider store={store}>
              <PersistGate loading={<LoadingIndicator />} persistor={persistor}>
                  <MainNavigator initialRoute={this.props.initialRoute} />
              </PersistGate>
            </Provider>
        );
      }
    }
    

    @components @actions 在这种情况下,导入由babel插件“模块解析器”解析

    B.法律改革委员会

    ...
    ["module-resolver", {
          "root": ["."],
          "alias": {
            "^@constants/(.+)": "./constants/\\1",
            "@i18n": "./i18n/index.js",
            "^@components/(.+)": "./components/\\1",
            "^@screens/(.+)": "./screens/\\1",
            "^@reducers/(.+)": "./reducers/\\1",
            "^@actions/(.+)": "./actions/\\1",
          }
        }]
    ...
    

    在route应用程序中导入的StorageConfigurationBuilder提供了存储区和持久化器,它只是:

    StorageConfigurationBuilder.js

    import { createStore } from 'redux'
    import { persistStore, persistReducer } from 'redux-persist'
    import storage from 'redux-persist/lib/storage/index.native'
    import AllReducers from '@reducers/AllReducers'
    //import Reactotron from '../../ReactronConfig'
    
    const persistConfig = {
        key: 'root',
        storage
    }
    const persistedReducer = persistReducer(persistConfig, AllReducers)
    
    export const store = createStore(persistedReducer)
    export const persistor = persistStore(store)
    

    最后是要渲染的视图组件,该组件分为两部分

    index.js

    import React, {Component} from 'react'
    import { connect } from 'react-redux';
    import LoginView from './LoginView';
    import {loginFetch, loginFetchError, loginFetchSuccess} from '@actions/UserActions'
    import ApiConfiguration, { getApiBaseUri } from '@constants/ApiConfiguration'
    
    class LoginController extends Component {
        constructor(props) {
            super(props)
        }
    
        doLogin() {
          this.props.dispatch(loginFetch());
    
          fetch(getApiBaseUri() + ApiConfiguration.endpoints.authentication.path, {
              ...ApiConfiguration.headers,
              method: ApiConfiguration.endpoints.authentication.method,
              body: JSON.stringify({
                email: this.props.email, 
                password: this.props.password
              })
            }).then((response) => {
              return response.json()
            }).then((response) => {
              this.props.dispatch(loginFetchSuccess(response))
            }).catch((e) => {
              this.props.dispatch(loginFetchError(e))
            })
        }
    
        render() {
            return <LoginView {...this.props} login={this.doLogin.bind(this)} />;
        }
    }
    
    const mapStateToProps = (state) => {
        const { user } = state
        return { user }
    };
    
    export default connect(mapStateToProps)(LoginController);
    

    <LoginView />

    LoginView.js

    import React from 'react';
    import {StyleSheet, SafeAreaView, View, TextInput, Text, TouchableOpacity} from 'react-native';
    import {changeEmail, changePassword} from '@actions/UserActions'
    import I18n from '@i18n';
    import Colors from '@constants/Colors';
    
    export default props => {
        return (<SafeAreaView style={styles.container}>
            <View style={styles.loginForm}>
    
                <View style={styles.fieldContainer}>
                    <Text style={styles.fieldLabel}>{I18n.t('login.email_label')}</Text>
                    <TextInput 
                        value={props.user.email}
                        onChangeText={value => props.dispatch(changeEmail(value))}
                        placeholder={I18n.t('login.email_placeholder')} 
                        style={styles.field} 
                        textContentType={"username"} 
                        returnKeyType={"next"}
                        underlineColorAndroid={"transparent"}></TextInput>
                </View>
    
                <View style={styles.fieldContainer}>
                    <Text style={styles.fieldLabel}>{I18n.t('login.password_label')}</Text>
                    <TextInput 
                        value={props.user.password}
                        onChangeText={value => props.dispatch(changePassword(value))}
                        style={styles.field}  
                        placeholder={I18n.t('login.password_placeholder')} 
                        textContentType={"password"} 
                        underlineColorAndroid={"transparent"}
                        secureTextEntry={true}></TextInput>
                </View>
    
                <View style={styles.panelFooter}>
                    <TouchableOpacity onPress={() => props.login()}>
                        <Text>
                            {I18n.t('login.login_button')}
                        </Text>
                    </TouchableOpacity>
                </View>
            </View>
        </SafeAreaView>);
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            backgroundColor: Colors.backgroundColor,
            justifyContent: 'center'
        },
        loginForm: {
            marginLeft: 20,
            marginRight: 20,
            justifyContent: 'space-around',
            borderWidth: 1,
            borderColor: Colors.borderColor,
            borderRadius: 5
        },
    
        panelFooter: {
            flexDirection: 'row',
            justifyContent: 'flex-end',
            backgroundColor: '#e5e5e5',
            height: 44,
            paddingRight: 20,
            paddingTop: 13,
            marginTop: 35
        },
    
        fieldContainer: {
            height: 50,
            flexDirection: 'column',
            marginLeft: 20,
            marginRight: 20,
            marginTop: 25
        },
        fieldLabel: {
            fontSize: 13,
            fontWeight: "600",
            marginBottom: 4,
            marginLeft: 10
        },
        field: {
            height: 44,
            borderWidth: 1,
            borderColor: Colors.borderColor,
            borderRadius: 22,
            fontSize: 18,
            paddingLeft: 22,
            paddingRight: 10
        }
    })
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   500 Server error    7 年前

    因此,我添加了一个简单的减速器/动作,并将其附加到我的应用程序中,与上述应用程序相同。我从另一个人那里得到了这个密码 standalone project

    在这一部分中,FriendReducer继续正常工作,而我上面描述的Reducer仍然不工作。

    case 'persist/REHYDRATE':
       //rehydrating userStore to app
       newState = { ...action.payload.userStore }
       return newState