我尝试实现用户验证的 redux 存储和操作出了什么问题?

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

我有 ButtonRegistration 组件,在按下注册按钮后我实现了一项工作。当用户按下按钮时,会出现带有输入字段的模式,用户可以输入他的数据(姓名、电子邮件、密码、确认密码)

const ButtonRegistration = () => {
  const dispatch = useDispatch();
  const user = useSelector((state) => state.user);
  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down("md"));
  const [open, setOpen] = useState(false);
  const [error, setError] = useState(user.errorMessage);

  /*Handler for Sign UP section*/
  
  const handleSignup = () => {
    dispatch(valideteNewUser(user));
  };

  /*Handlers for Button-Dialog section*/

  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  /*Handler for Modal section*/

  const handleCloseErrorMessage = () => {
    setError(null);
  };

  return (
    <div style={{ marginLeft: "1rem" }}>
      {/*section Button-Dialog*/}

      <Button
        onClick={handleClickOpen}
        variant="outlined"
        size="small"
        sx={{ background: "rgb(177, 209, 227);" }}
      >
        Registration
      </Button>
      <Dialog
        fullScreen={fullScreen}
        open={open}
        onClose={handleClose}
        PaperProps={{
          component: "form",
          onSubmit: (event) => {
            event.preventDefault();
            const formData = new FormData(event.currentTarget);
            const formJson = Object.fromEntries(formData.entries());
            const email = formJson.email;
            console.log(email);
            handleClose();
          },
        }}
      ></Dialog>

      {/*section Modal*/}

      <Modal
        aria-labelledby="modal-title"
        aria-describedby="modal-desc"
        open={open}
        onClose={() => setOpen(false)}
        sx={{
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
        }}
      >
        <Sheet
          variant="outlined"
          sx={{
            maxWidth: 500,
            borderRadius: "md",
            p: 3,
            boxShadow: "lg",
          }}
        >
          <ModalClose
            variant="plain"
            sx={{ m: 1 }}
            onClick={handleCloseErrorMessage}
          />
          <Typography
            component="h2"
            id="modal-title"
            level="h4"
            textColor="inherit"
            fontWeight="lg"
            mb={1}
          >
            Registration
          </Typography>

          {/*section Sign UP*/}

          <Box
          >
            <Input
              size="lg"
              value={user.name}
              onChange={(e) => dispatch(setName(e.target.value))}
              type="text"
              placeholder="Enter your name..."
            ></Input>
            <Input
              size="lg"
              value={user.email}
              onChange={(e) => dispatch(setEmail(e.target.value))}
              type="text"
              placeholder="Enter email..."
            ></Input>
            <Input
              size="lg"
              value={user.password}
              onChange={(e) => dispatch(setPassword(e.target.value))}
              type="password"
              placeholder="Enter password..."
            ></Input>
            <Input
              size="lg"
              value={user.confirmdPassword}
              onChange={(e) => dispatch(setConfirmPassword(e.target.value))}
              type="password"
              placeholder="Confirm password..."
            ></Input>
            <Button size="md" onClick={handleSignup}>
              Register
            </Button>
            {error && (
              <Typography variant="body2" color="error">
                {error}
              </Typography>
            )}
          </Box>
        </Sheet>
      </Modal>
    </div>
  );
};

export default ButtonRegistration;

当用户输入不正确的数据时,我使用 Joi 检查:

const Joi = require("joi");

const validator = (scheme) => (payload) =>
  scheme.validate(payload, { abortEarly: false });

const signupSchema = Joi.object({
  name: Joi.string().required(),
  email: Joi.string().email({ tlds: { allow: false } }).required(),
  password: Joi.string().min(3).max(10).required(),
  confirmPassword: Joi.ref("password"),
});

exports.validateRegister = validator(signupSchema);

我尝试通过在 ButtonRegistartion 组件中使用变量错误来呈现有关错误输入数据的消息。我有以下操作和减速器:

行动

export const valideteNewUser = (name, email, password, confirmPassword) => ({
  type: VALIDATE_USER,
  payload: {
    name,
    email,
    password,
    confirmPassword,
  },
});

export const setName = (name) => ({
  type: SET_NAME,
  payload: name,
});

export const setEmail = (email) => ({
  type: SET_EMAIL,
  payload: email,
});

export const setPassword = (password) => ({
  type: SET_PASSWORD,
  payload: password,
});

export const setConfirmPassword = (confirmPassword) => ({
  type: SET_CONFIRM_PASSWORD,
  payload: confirmPassword,
});

export const setErrorMessage = (errorMessage) => ({
  type: ERROR_MESSAGE,
  payload: errorMessage,
});

减速机:

export const initialState = {
  user: {
    name: "",
    email: "",
    password: "",
    confirmdPassword: "",
    errorMessage: null,
  },
};

export function userReducer(state = initialState, action) {
  switch (action.type) {
    case VALIDATE_USER:
      const { error } = validateRegister({
        name: action.payload.name,
        email: action.payload.email,
        password: action.payload.password,
        confirmPassword: action.payload.confirmPassword,
      });
      if (error) {
        return {
          ...state,
          errorMessage: error.details.map((d) => d.message).join(", "),
        };
      } else {
        return {
          ...state,
          errorMessage: null,
        };
      }

    case SET_NAME:
      return {
        ...state,
        user: {
          ...state.user,
          name: action.payload,
        },
      };

    case SET_EMAIL:
      return {
        ...state,
        user: {
          ...state.user,
          email: action.payload,
        },
      };

    case SET_PASSWORD:
      return {
        ...state,
        user: {
          ...state.user,
          password: action.payload,
        },
      };

    case SET_CONFIRM_PASSWORD:
      return {
        ...state,
        user: {
          ...state.user,
          confirmPassword: action.payload,
        },
      };

    case ERROR_MESSAGE:
      return {
        ...state,
        user: {
          ...state.user,
          errorMessage: action.payload,
        },
      };

    default:
      return state;
  }
}

当用户输入不正确的数据时,不会出现任何内容,但同时我在 Redux devTools 中看到我的 errrorMessage 发生了变化。

如何实现错误输入的渲染。提前谢谢?

javascript reactjs redux react-redux joi
1个回答
0
投票

ButtonRegistration
错误地将所选的
user.errorMessage
状态复制到本地状态。这是一个 React 反模式。基本要点是,当存储中的
error
值更新时,本地
user.errorMessage
状态不会更新。

更新

ButtonRegistration
组件以直接引用和更新
user.errorMessage
状态。

const ButtonRegistration = () => {
  const dispatch = useDispatch();

  const user = useSelector((state) => state.user); // <-- includes errorMessage

  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down("md"));

  const [open, setOpen] = useState(false);

  /*Handler for Sign UP section*/
  const handleSignup = () => {
    dispatch(validateNewUser(user)); // <-- updates user.errorMessage
  };

  ...

  /*Handler for Modal section*/
  const handleCloseErrorMessage = () => {
    dispatch(setErrorMessage(null)); // <-- clear user.errorMessage state
  };

  return (
    <div ... >
      ...

      <Modal ... >
        <Sheet ... >
          ...

          <Box>
            ...

            {user.errorMessage && (
              <Typography variant="body2" color="error">
                {user.errorMessage}
              </Typography>
            )}
          </Box>
        </Sheet>
      </Modal>
    </div>
  );
};

export default ButtonRegistration;
© www.soinside.com 2019 - 2024. All rights reserved.