简体   繁体   中英

Invalid hook call. useDispatch . Redux

I tried many things but I still have the error message "[Unhandled promise rejection: Error: Invalid hook call. Hooks can only be called inside of the body of a function component.".

I was using Context API still now and I migrate my App to Redux. I'm trying to do a simple thing: When I press a button I want it to call a function that will call my reducers based on the input.

Screen Signup.js:


    const SignUp = ({ navigation }) => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [pseudo, setPseudo] = useState("");
  const state = useSelector((state) => state.AuthReducer);
  
  return (
    <View style={styles.container}>  

        ...other stuffs
        
          <Button
            title="test"
            onPress={() => signUp({ email, pseudo, password, confirmPassword })}
          />
    </View>
  );
};

My authReducer.js

export const AuthReducer = (state = 0, action) => {
  switch (action.type) {
    case "signin":
      return {
        errorMessage: "",
        token: action.payload,
      };
    case "add_error":
      return { ...state, errorMessage: action.payload };

    ....Other cases....
    
    default:
      return state;
  }
};


export const signUp = async ({ email, pseudo, password, confirmPassword }) => {
  const dispatch = useDispatch();

 
  try {
    response = await trackerApi.post("/api/signup", {
      email,
      pseudo,
      password,
    });
    await AsyncStorage.setItem("token", response.data.token);
    dispatch({
      type: "signin",
      payload: response.data.token,
    });
    RootNavigation.navigate("Tabs");
  } catch (err) {
    const { response } = err;
    const { request, ...errorObject } = response;
    let message = errorObject.data;
    dispatch({
      type: "add_error",
      payload: message,
    });
  }
};

Even simple function like this doesn't work:

export const signUp = async ({ email, pseudo, password, confirmPassword }) => {
  const dispatch = useDispatch();

  dispatch({ type: "add_error", payload: "test" });
};

useDispatch is a hook and thus can only be called inside a functional component. You are calling the hook inside signup method and that is why it is throwing the error.

Try this in your SignUp component -

const SignUp = ({ navigation }) => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [pseudo, setPseudo] = useState("");
  const state = useSelector((state) => state.AuthReducer);
  const dispatch = useDispatch();

  return (
    <View style={styles.container}>  

        ...other stuffs
        
          <Button
            title="test"
            onPress={() => signUp({ email, pseudo, password, confirmPassword }, dispatch)}
          />
    </View>
  );
};

and in signup , like this -

export const signUp = async ({ email, pseudo, password, confirmPassword }, dispatch) => {

 
  try {
    response = await trackerApi.post("/api/signup", {
      email,
      pseudo,
      password,
    });
    await AsyncStorage.setItem("token", response.data.token);
    dispatch({
      type: "signin",
      payload: response.data.token,
    });
    RootNavigation.navigate("Tabs");
  } catch (err) {
    const { response } = err;
    const { request, ...errorObject } = response;
    let message = errorObject.data;
    dispatch({
      type: "add_error",
      payload: message,
    });
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM