减速器总是返回初始状态React-native

时间:2019-01-01 17:46:28

标签: reactjs redux react-redux redux-thunk reducers

我想使用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;

router.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

2 个答案:

答案 0 :(得分:0)

您似乎没有调度任何动作。

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);

答案 1 :(得分:0)

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

<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});
}

此外,您应该使用相同的密码方式。