如何修复在调度之间检测到的状态突变

问题描述 投票:0回答:0

我在按下登录按钮时收到以下错误消息。我确定发生了什么,但我找不到解决这个问题的方法。

错误:不变失败:在路径“auth.user._2”中的调度之间检测到状态突变。这可能会导致不正确的行为。 (https://redux.js.org/style-guide/style-guide#do-not-mutate-state

登录屏幕

import React, {useState, useLayoutEffect} from 'react';
import {Alert, Image, Text, TouchableOpacity, View,  StyleSheet} from 'react-native';
import {TextInput} from 'react-native-paper';

import Container from '../components/Container';
import Content from '../components/Content';
import { useNavigation } from "@react-navigation/native";
import { login } from "./../actions/auth";
import { useDispatch } from "react-redux";

const LoginScreen  = ({navigation}) => {

  const navigationTo = useNavigation();
  const [passwordVisible, setPasswordVisible] = useState(true);

  const [email, setEmail] = useState();
  const [password, setPassword] = useState();
  const [loader, setLoader] = useState(false);
  const [loginText, setLoginText] = useState('Sign In');
  const dispatch = useDispatch();

  const onConnect = () => {
    let userLogin = {
      email: email,
      password: password,
    };
    if(email && password) {
      setLoader(true);
      setLoginText('Sign In...');
      dispatch(login(userLogin))
        .then((response) => {
          if (response.status == "success") {
            navigation.replace("Home");
          }
        })
        .catch((error) => {
          setLoader(false);
          alert('Your credentials are invalid!');
          setLoginText('Sign In');
        });
    }
  };

  useLayoutEffect(() => {
    navigation.setOptions({
      headerShown: false,
    });
  }, []);

  return (
    <Container insets={{top: true, bottom: true}}>
      <Content>
        <View style={{flex: 1}}>
          <View style={styles.topContainer}>
            <View style={{flexDirection: 'row', alignItems: 'center'}}></View>
            <Image
              style={styles.logo}
              source={require('../assets/xorixBlack.png')}
            />
          </View>

          <View style={styles.keyboardView}>
            <TextInput
              theme={{colors: {text: '#000'}}}
              placeholder="Email address"
              placeholderTextColor="black"
              selectionColor="black"
              style={styles.textInput}
              textColor={'black'}
              value={email}
              onChangeText={(text) => setEmail(text)}
            />

            <TextInput
              theme={{colors: {text: 'black'}}}
              placeholder="Password"
              placeholderTextColor="black"
              value={password}
              onChangeText={(text) => setPassword(text)}
              style={styles.textInput}
              selectionColor="black"
              secureTextEntry={passwordVisible}
              textColor={'black'}
              right={
                <TextInput.Icon
                  color={'black'}
                  name={passwordVisible ? 'eye-off' : 'eye'}
                  onPress={() => setPasswordVisible(!passwordVisible)}
                />
              }
            />
            <TouchableOpacity
              onPress={() => onConnect()}
              disabled={loader}
              style={styles.loginBtn}>
              <Text style={styles.loginText}>{loginText}</Text>
            </TouchableOpacity>

            <View style={{alignItems: 'center', padding: 10}}>
              <View style={styles.text}>
                <Text style={{fontSize: 12, color: 'black'}}>
                  Forgot your password?{' '}
                </Text>
                <Text style={styles.help}> Click here to reset</Text>
              </View>

              <View style={styles.seperatorStyle}>
                <View style={styles.seperator} />
                <Text style={{color: 'black'}}> OR </Text>
                <View style={styles.seperator} />
              </View>

              <View style={styles.facebook}>
                <TouchableOpacity
                  onPress={() => navigationTo.navigate("Home")}>
                  <Text style={styles.faceText}>Sign Up</Text>
                </TouchableOpacity>
              </View>
            </View>
          </View>

  
        </View>
      </Content>
    </Container>
  );
};
export default LoginScreen;

actions/auth.js

import { LOGIN_SUCCESS, LOGOUT } from "./type";
import AuthService from "../services/authService";
export const login = (user) => (dispatch) => {
  return AuthService.logIn(user).then(
    (response) => {
        console.log(response)
      if (response.status === "success") {
        dispatch({
          type: LOGIN_SUCCESS,
          payload: { user: response.user },
        });
Promise.resolve();
        return response;
      }
    },
    (error) => {
      const message = error.toString();
Promise.reject();
      return message;
    }
  );
};

export const logout = () => (dispatch) => {
  return AuthService.logOut().then((response) => {
    if (response.status === "success") {
      dispatch({
        type: LOGOUT,
      });
      Promise.resolve();
      return response;
    }
  });
};

服务/authService.js

    import AsyncStorage from "@react-native-async-storage/async-storage";
const logIn = async (user) => {
    console.log("user info", user);
    const { email, password } = user;
    return fetch('https://myapi.com/api/orders/login.json', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json;charset=UTF-8', "Access-Control-Allow-Origin": "*", "Accept": "application/json" },
      body: JSON.stringify({
        "email": email,
        "password": password
      })
    })
    .then((response) => response.json())
    .then((responseJson) => {
      if(responseJson.json.error === false) {
        console.log('successfulll');
        AsyncStorage.setItem("user", JSON.stringify(responseJson.json.user));
        return {
          status: "success",
          message: "You are redirecting to home page",
          user: email,
        };
      } else {
        return {
          status: "error",
          message: "Wrong credentials"
        };
      }
    })
    .catch((error) => {
      return {
        status: "error",
        message: "API call failed"
      };
    });
  };
const logOut = async () => {
  AsyncStorage.clear();
  return {
    status: "success",
    message: "You are logged out",
  };
};
export default {
  logIn,
  logOut,
};
reactjs react-native redux
© www.soinside.com 2019 - 2024. All rights reserved.