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

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中看到我的erroryMessage发生变化的同时.

如何实现不正确输入的渲染.提前感谢?

推荐答案

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

更新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;

Javascript相关问答推荐

为什么使用MAX_SAFE_INTEGER生成随机整数时数字分布不准确?

fetch在本地设置相同来源的cookie,但部署时相同的代码不会设置cookie

JavaScript文本区域阻止KeyDown/KeyUp事件本身上的Alt GR +键组合

对象和数字减法会抵消浏览器js中的数字

Vue:ref不会创建react 性属性

fs. writeFile()vs fs.writeFile()vs fs.appendFile()

通过嵌套模型对象进行Mongoose搜索

Next.js(react)使用moment或不使用日期和时间格式

Angular material 拖放堆叠的牌副,悬停时自动展开&

空的结果抓取网站与Fetch和Cheerio

Chromium会将URL与JS一起传递到V8吗?

我的角模板订阅后不刷新'

制作钢琴模拟器,并且在控制台中不会执行或显示该脚本

提交链接到AJAX数据结果的表单

映射类型定义,其中值对应于键

是否可以在Photoshop CC中zoom 路径项?

在验证和提交表单后使用useNavigate()进行react 重定向,使用带有加载器和操作的路由

处理app.param()中的多个参数

我为什么要使用回调而不是等待?

Firebase函数中的FireStore WHERE子句无法执行