Reducer 总是返回初始状态 React-native

Posted

技术标签:

【中文标题】Reducer 总是返回初始状态 React-native【英文标题】:Reducer always returning initial state React-native 【发布时间】:2019-05-28 14:03:24 【问题描述】:

我想使用 Reducers、redux、thunk。我有一个示例代码。 当我开始项目时,运行没有错误。我想更改电子邮件第一个字母出现并返回初始值。 我确实在这个 package.json 中使用了这些代码,但是当我更新所有库时,一些函数会崩溃。我在帖子末尾分享了 finale package.json 文件。 package.json 文件:


  "main": "node_modules/expo/AppEntry.js",
  "private": true,
  "dependencies": 
    "expo": "^25.0.0",
    "lodash": "^4.17.4",
    "react": "16.2.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-25.0.0.tar.gz",
    "react-native-router-flux": "^3.40.1",
    "react-redux": "^5.0.6",
    "react-router-native": "^4.2.0",
    "redux": "^3.7.2",
    "redux-thunk": "^2.2.0"
  

请看我的 gif。Problem Gif

App.js

import React,  Component  from 'react';
import  Provider  from 'react-redux';
import  createStore, applyMiddleware  from 'redux';
import ReduxThunk from 'redux-thunk';
import reducers from './src/reducers';
import Router from './src/Router';


class App extends Component 
  render() 
    const store = createStore(reducers, applyMiddleware(ReduxThunk));
    return (
      <Provider store=store>
        <Router />
      </Provider>
    );
  


export default App;

路由器.js

import React from 'react';
import Scene, Router, Stack from 'react-native-router-flux';
import Login from './components/Login';

const RouterComponent = () => 
  return (
    <Router navigationBarStyle=backgroundColor: 'transparent'>
      <Stack key="root">
          <Scene key="Login" component=Login title="Giriş Yap" backTitle=" " hideNavBar=true type="reset" initial/>
      </Stack>
    </Router>

  );
;

export default RouterComponent;

这是我的 Login.js 我想在 textinput 中更改邮箱或密码返回初始值

import React,  Component  from 'react';
import  TextInput, View  from 'react-native';
import  Actions  from 'react-native-router-flux';
import  connect  from 'react-redux';
import  emailChanged, passwordChanged, loginUser  from '../actions';
import  KucukButton  from '../ortak';

class Login extends Component 
  state = email: '', password: '', loading: false ;

clickLogin() 
  const  email, password  = this.props;
  this.props.loginUser( email, password );


loginSucces() 
  console.log('başarılı');
  this.setState( loading: false );



loginFail() 
  console.log('Hatalı');
  this.setState( loading: false );
  Alert.alert(
    'Mesaj',
    'Kullanıcı adı veya şifreniz hatalı!',
    [
       text: 'Tamam', onPress: () => null 
    ]
  );

  render() 
    return (
       <View
        style=
          justifyContent: 'center',
          flex: 1
        >
            <TextInput
              autoCapitalize="none"
              keyboardType="email-address"
              placeholder="örn hesap: test@test.com"
              placeholderTextColor="#000"
              value=this.props.email
              onChangeText=email => this.props.emailChanged(email)
            />
            <KucukButton yazisiz="hayir" onPress=this.clickLogin.bind(this)> Giriş Yap </KucukButton>
      </View>
    );
  

const mapStateToProps = ( kimlikdogrulamaResponse ) => 
  const email, password = kimlikdogrulamaResponse;
  return 
    email,
    password
  ;
;

export default connect(mapStateToProps,  emailChanged, passwordChanged, loginUser )(Login);

这是我的actions.js

import  EMAIL_CHANGED, PASSWORD_CHANGED  from './types';

export const emailChanged = (email) => 
  return (dispatch) => 
    dispatch(
      type: EMAIL_CHANGED,
      payload: email
    );
  ;
;


export const passwordChanged = (password) => 
  return (dispatch) => 
    dispatch(
      type: PASSWORD_CHANGED,
      payload: password
    );
  ;
;

types.js

export const EMAIL_CHANGED = 'email_changed';
export const PASSWORD_CHANGED = 'password_changed';

Reducers.js

import  EMAIL_CHANGED, PASSWORD_CHANGED  from '../actions/types';

const INITIAL_STATE = 
  email: '00000000',
  password: ''
;

export default (state = INITIAL_STATE, action) => 
  switch (action.type) 
    case EMAIL_CHANGED:
        return  ...state, email: action.payload ;
    case PASSWORD_CHANGED:
      return  ...state, password: action.payload ;
  default:
      return state;

  
;

最后是我的 package.json 文件:


  "main": "node_modules/expo/AppEntry.js",
  "scripts": 
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "eject": "expo eject"
  ,
  "dependencies": 
    "expo": "^31.0.2",
    "firebase": "^5.7.2",
    "lodash": "^4.17.11",
    "react": "16.5.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",
    "react-native-router-flux": "^4.0.6",
    "react-redux": "^6.0.0",
    "react-router-native": "^4.3.0",
    "redux": "^4.0.1",
    "redux-thunk": "^2.3.0"
  ,
  "devDependencies": 
    "babel-preset-expo": "^5.0.0"
  ,
  "private": true

编辑:: 你可以看看我的零食进行测试。 Snack Expo Application

【问题讨论】:

【参考方案1】:

您似乎没有发送任何操作。

在您的Login 组件中,您调用在actions 文件中定义的函数,但这会返回另一个没有调用的函数。

您可以尝试将登录中的道具映射为:

const mapDispatchToProps = dispatch => (
    emailChanged: email => emailChanged(email)(dispatch)
);

密码同上。

即使这应该有效,您的模式也有点奇怪。在您的情况下,您可以通过这种方式重组代码以获得更清晰的理解:

const mapDispatchToProps = dispatch => (
    emailChanged: email => dispatch(emailChanged(email))
);

你的行为如下:

export const emailChanged = email => (
   type: EMAIL_CHANGED,
   payload: email
);

在上述两种情况下,引入 mapDispatchToProps,那么你的connect 应该是这样的:

export default connect(mapStateToProps, mapDispatchToProps)(Login);

【讨论】:

谢谢。我尝试了您的解决方案,但它不起作用。 Login.js:** const mapStateToProps = ( kimlikdogrulamaResponse ) => const email, password = kimlikdogrulamaResponse;返回电子邮件,密码; ; const mapDispatchToProps = dispatch => ( emailChanged: email => dispatch(emailChanged(email)), passwordChanged: password => dispatch(passwordChanged(password)) );导出默认连接(mapStateToProps,mapDispatchToProps)(登录); ** actions.js** export const emailChanged = email => ( type: EMAIL_CHANGED, payload: email );**【参考方案2】:

现在您分派每一次击键,这不是最佳做法。而不是这样做,您应该将电子邮件和密码值写入状态。

<TextInput
    autoCapitalize="none"
    keyboardType="email-address"
    placeholder="örn hesap: test@test.com"
    placeholderTextColor="#000"
    defaultValue=this.props.email //use defaultValue
    onChangeText=(email) => this.setState(email) //use state
/>

之后,您应该在登录功能中由您的操作创建者发送 this.state.email。

clickLogin() 
    const email, password = this.props;
    this.props.emailChanged(this.state.email) //now you should dispatch
    this.props.loginUser(email, password);

您也应该使用相同的方式输入密码。

【讨论】:

谢谢,但它不起作用。控制台日志返回未定义。 你的 console.log 语句在哪里?

以上是关于Reducer 总是返回初始状态 React-native的主要内容,如果未能解决你的问题,请参考以下文章

React 组件没有得到 reducer 设置的 redux 初始状态

使用 Typescript 的 Redux reducer 初始状态

在 Redux Reducer 中读取 Store 的初始状态

React Redux Reducer 触发但不改变状态

无法初始化商店的状态

减速器中加载的默认状态总是正确的?