Javascript 在React本机组件中处理HTTP响应的正确方法是什么

Javascript 在React本机组件中处理HTTP响应的正确方法是什么,javascript,reactjs,react-native,redux,Javascript,Reactjs,React Native,Redux,我正在构建一个移动应用程序,并使用Django REST框架作为后端。我也在使用Redux。我正在使用的API之一是验证OTP代码。如果OTP代码匹配,那么如果这是新用户或不是新用户,我将使用服务器的响应重新调整。如果是新用户,我会将其重定向到注册屏幕,如果不是,我会将其重定向到登录屏幕,这是我的问题 我将服务器的响应存储在redux存储中名为isNewUser的变量中。然后,我使用useSelector在我的组件中访问它。当我在输入OTP代码后点击按钮时,我发送两个动作。首先是验证OTP的那个

我正在构建一个移动应用程序,并使用Django REST框架作为后端。我也在使用Redux。我正在使用的API之一是验证OTP代码。如果OTP代码匹配,那么如果这是新用户或不是新用户,我将使用服务器的响应重新调整。如果是新用户,我会将其重定向到注册屏幕,如果不是,我会将其重定向到登录屏幕,这是我的问题

我将服务器的响应存储在redux存储中名为isNewUser的变量中。然后,我使用useSelector在我的组件中访问它。当我在输入OTP代码后点击按钮时,我发送两个动作。首先是验证OTP的那个。第二个是用于登录的分派或用于注册操作的分派,这取决于我从redux商店获得的变量isNewUser

问题是,当我分派第一个操作时,即验证OTP并存储isNewUser变量,该变量的值在下一次渲染之前不会在我的组件中更新,因此在再次单击按钮以便更新变量的值之前,我无法分派第二个操作

那么如何解决这个问题呢?我不知道我的实现是否正确,或者是否有更好的实现

这是我的操作代码,我还没有编写登录和注册操作的代码

export const validateOTP = (otp, mobileNum) => {
  return async dispatch => {
    const response = await fetch("http://localhost:8000/api/validate_otp", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        otp: otp,
        mobile: mobileNum
      })
    });
    if (!response.ok) {
      const errorResData = await response.json();
      console.log(errorResData);
    }

    const resData = await response.json();
    if (resData.status === false) {
      throw new Error(resData.detail);
    } else {
      const isNewUser = resData.isNewUser;
      dispatch({
        type: VALIDATE_OTP,
        isNewUser: isNewUser
      });
    }
  };
};
以下是我的减速机代码:

import { VALIDATE_OTP } from "../actions/auth";

const initialState = {
  isNewUser: null
};

export default (state = initialState, action) => {
  switch (action.type) {
    case VALIDATE_OTP: {
      const isNewUserVal = action.isNewUser;
      return {
        ...state,
        isNewUser: isNewUserVal
      };
    }
  }
  return state;
};
以下是React本机组件的示例代码:

const CodeEntryScreen = props => {
  const dispatch = useDispatch();
  const isNewUser = useSelector(state => state.auth.isNewUser)
  const [error, setError] = useState();


  useEffect(() => {
    if (error) {
      Alert.alert("An Error Occurred", error, [{ text: "Okay" }]);
    }
  }, [error]);

  const validateOTPHandler = async () => {
    setError(null);
    try {
      await dispatch(authActions.validateOTP(otp, mobileNum));
      console.log(isNewUser)
     if(isNewUser) {
        // dispatch resgister action
      }
      else {
        // dispatch  login action 
      }
    } catch (err) {
      setError(err.message);
    }
  };

您只需稍加修改即可解决此问题。更简单的是:

1) 在
validateOTPHandler
在您的
validateOTP
函数中,最后有以下内容:

调度({
类型:验证OTP,
isNewUser:isNewUser
});
将函数改为返回该值:

返回调度({
类型:验证OTP,
isNewUser:isNewUser
});
通过该更改,在组件中,您可以通过以下方式访问操作的有效负载:

const validateOTPHandler=async()=>{
设置错误(空);
试一试{
const{isNewUser:isNew}=wait分派(authActions.validateOTP(otp,mobileNum));
console.log(isNew)
如果(是新的){
//分派重新注册操作
}
否则{
//调度登录操作
}
}捕捉(错误){
设置错误(错误消息);
}
};
这是一个更容易的改变,让它按照你的意愿工作

2)
useffect
我认为这与你想象中的流程更为相似:

  • 验证代码(更新存储)
  • 重新渲染:您获得了新值
  • 现在做一些事情:登录或注册
但要做到这一点,您需要使用
useffect
,以便收听您以这种方式所做的更改:

constcodentryscreen=props=>{
const dispatch=usedpatch();
const isNewUser=useSelector(state=>state.auth.isNewUser)
const[error,setError]=useState();
const[success,setSuccess]=useState(false);//ValidateOp成功时为true
useffect(()=>{
如果(错误){
Alert.Alert(“发生错误”,错误,[{text:“Okay”}]);
}
},[错误];
useffect(()=>{
如果(成功){
//ValidateOp成功…让我们检查isNewUser:)
if(isNewUser){
//调度登记簿
}否则{
//调度登录
}
}
},[success,isNewUser]);
const validateOTPHandler=async()=>{
设置错误(空);
设置成功(假);
试一试{
等待调度(authActions.validateOTP(otp,mobileNum));
设置成功(true);
}捕捉(错误){
设置错误(错误消息);
}
};