首页 > 解决方案 > 禁用受控表单上的提交按钮反应

问题描述

我目前正在处理 React.js 中的表单。我想添加一些输入控件并相应地禁用/启用提交按钮。但是,我无法使其正常工作,并且我确信有更好的方法来做到这一点。

这是我想要实现的目标:

这是我的代码:

import React, { useEffect, useState, useContext } from "react";
import { useLocation, Link, useHistory } from "react-router-dom";

import _ from "lodash"; // Usefull library used here on array
import uuid from "react-uuid"; // generate Dynamic ID

// material-ui component library (build faster/beautiful/more accessible)
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";
import ArrowBackIcon from "@material-ui/icons/ArrowBack";

import { BookmarkContext } from "../../context/BookmarkContext"; // import the context

import firebase from "firebase/app"; // import firebase DB
import "firebase/database";

// add a litle style
const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
    padding: theme.spacing(3),
  },
  paper: {
    padding: theme.spacing(2),
    color: theme.palette.text.secondary,
  },
  button: {
    marginTop: theme.spacing(2),
  },
}));

const ManageBookmark = () => {
  const classes = useStyles();

  let location = useLocation(); // location object with/without singleBookmark data
  let history = useHistory(); // navigate user

  let database = firebase.database();

  const { bookmarkData } = useContext(BookmarkContext); // load context

  const [id, setID] = useState(null);
  const [url, setUrl] = useState(null);
  const [title, setTitle] = useState(null);
  const [height, setHeight] = useState(null);
  const [width, setWidth] = useState(null);
  const [length, setLength] = useState(null);
  const [keywords, setKeywords] = useState(null);

  const [isIncorrectdURL, setIncorrectURL] = useState(false);
  const [isIncorrectTitle, setIncorrectTitle] = useState(false);

  const [disableSentButton, setdisableSentButton] = useState(true); // disable button on page load

  useEffect(() => {
    const DATA = location.state.singleBookmark;

    if (DATA) {
      // if Data, we populate the form
      setID(DATA.id);
      setUrl(DATA.url);
      setTitle(DATA.title);
      setHeight(DATA.height);
      setWidth(DATA.width);
      setLength(DATA.length);
      setKeywords(_.join(DATA.keywords, ","));
    }
  }, []);

  const handleUrlChange = (event) => {
    setUrl(event.target.value);

    const URL = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi;
    var regex = new RegExp(URL);

    // console.log(event.target.value);
    // console.log(event.target.value.match(regex));

    // event.target.value.match(regex)
    //   ? setIncorrectURL(false)
    //   : setIncorrectURL(true);

    if (event.target.value.match(regex)) {
      setIncorrectURL(false);
      console.log(
        "handleUrlChange (set to false) isIncorrectdURL",
        isIncorrectdURL
      );
    } else {
      setIncorrectURL(true);
      console.log(
        "handleUrlChange (set to true isIncorrectdURL",
        isIncorrectdURL
      );
    }
    isFormInvalide();
  };

  const handleTitleChange = (event) => {
    setTitle(event.target.value);
    event.target.value.length >= 1
      ? setIncorrectTitle(false)
      : setIncorrectTitle(true);
      isFormInvalide();
  };

  const handleHeightChange = (event) => {
    setHeight(event.target.value);
  };

  const handleWidthChange = (event) => {
    setWidth(event.target.value);
  };

  const handleLengthChange = (event) => {
    setLength(event.target.value);
  };

  const handleKeywordsChange = (event) => {
    setKeywords(event.target.value.trim()); // remove space on input onChange
  };

  const onCreateClick = () => {
    const id = uuid(); // generate id

    const bookmark = {
      id: id,
      url: url,
      title: title,
      width: width,
      height: height,
      createDate: new Date(),
      length: length,
      keywords: keywords ? keywords.split(",") : [],
    };

    // setBookmarkData((prevState) => _.concat(prevState, [bookmark]));

    // Create Bookmark inside firebase DB
    database.ref(`bookmarks/${id}`).set(bookmark);

    // redirect user to BookmarkHome component
    history.push({
      pathname: "/",
    });
  };

  const onEditClick = () => {
    const bookmark = {
      id: id || "",
      url: url || "",
      title: title || "",
      width: width || "",
      height: height || "",
      createDate: new Date(),
      length: length || "",
      keywords: keywords.split(",") || "",
    };

    const index = bookmarkData.findIndex((item) => {
      return item.id === id;
    });

    if (index !== -1) {
      // setBookmarkData([
      //   ...bookmarkData.slice(0, index),
      //   bookmark,
      //   ...bookmarkData.slice(index + 1),
      // ]);

      // Update DB
      database.ref(`bookmarks/${id}`).set(bookmark);

      history.push({
        pathname: "/",
      });
    }
  };

  const onSubmitClick = () => {
    // const onSubmitClick = (e) => {
    // e.preventDefault();
    id ? onEditClick() : onCreateClick();
  };


  const isFormInvalide = () => {
    console.log("isIncorrectdURL", isIncorrectdURL);
    console.log("isIncorrectTitle", isIncorrectTitle);

    if (isIncorrectdURL || isIncorrectTitle) {
      console.log("Il y a une erreur dans le form");
      setdisableSentButton(true);
      return true;
    } else {
      console.log("false");
      setdisableSentButton(false);
      return false;
    }
  };


  return (
    <div className={classes.root}>
      <Grid container spacing={3}>
        <Link to="/">
          <ArrowBackIcon />
        </Link>
        <Grid item xs={12}>
          <Paper className={classes.paper}>
            <Grid container spacing={3}>
              <Grid item xs={12}>
                <Typography variant="h3">
                  {id ? "Modifier un bookmark" : "Créer un bookmark"}
                </Typography>
              </Grid>
              <Grid item xs={4}>
                <form>
                  {/* <form onSubmit={onSubmitClick}> */}
                  <TextField
                    required
                    id="url-input"
                    label="Url"
                    variant="outlined"
                    fullWidth
                    margin="dense"
                    value={url || ""}
                    onChange={handleUrlChange}
                    error={isIncorrectdURL}
                    helperText={isIncorrectdURL && "Saisissez une URL."}
                  />
                  <TextField
                    required
                    id="title-input"
                    label="Titre"
                    variant="outlined"
                    fullWidth
                    margin="dense"
                    value={title || ""}
                    onChange={handleTitleChange}
                    error={isIncorrectTitle}
                    helperText={
                      isIncorrectTitle && "Le titre ne dois pas etre null"
                    }
                  />
                  <TextField
                    required
                    id="height-input"
                    label="Hauteur"
                    variant="outlined"
                    fullWidth
                    margin="dense"
                    value={height || ""}
                    onChange={handleHeightChange}
                    type="number"
                  />
                  <TextField
                    required
                    id="width-input"
                    label="Largeur"
                    variant="outlined"
                    fullWidth
                    margin="dense"
                    value={width || ""}
                    onChange={handleWidthChange}
                    type="number"
                  />
                  <TextField
                    required
                    id="length-input"
                    label="Durée"
                    variant="outlined"
                    fullWidth
                    margin="dense"
                    value={length || ""}
                    onChange={handleLengthChange}
                    type="number"
                  />
                  <TextField
                    required
                    id="keywords-input"
                    label="Keywords"
                    variant="outlined"
                    fullWidth
                    margin="dense"
                    value={keywords || ""}
                    onChange={handleKeywordsChange}
                  />
                  <Typography variant="caption" color="initial">
                    Séparez les tags par une virgule.
                  </Typography>

                  <Button
                    variant="contained"
                    color="primary"
                    // disabled={isFormInvalide}
                    disabled={disableSentButton}
                    // disabled={true} Disable BUTTON
                    onClick={onSubmitClick} // handle form submisison
                    fullWidth
                    className={classes.button}
                  >
                    {id ? "Mettre à jour le Bookmark" : "Créer le Bookmark"}
                  </Button>
                </form>
              </Grid>
            </Grid>
          </Paper>
        </Grid>
      </Grid>
    </div>
  );


   };
    
    export default ManageBookmark;

标签: reactjs

解决方案


推荐阅读