当用户点击取消文件选择时,我如何处理未定义的状态?

How do I handle undefined state in react when the user hits cancel on file selection?

我有一个简单的 Input type= 文件。我正在捕获处于状态的选定文件。选择文件并单击清除按钮后,它不会清除状态。这会导致

{selectedFile.name}

在用户在下一次文件选择期间单击取消时抛出未定义的错误。

有没有办法让我的清除按钮真正清除selectedFile状态?或处理错误以便仍然可以选择文件的方法?

import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import AddIcon from "@mui/icons-material/Add";
import { withStyles } from "@material-ui/core/styles";
import Fab from "@mui/material/Fab";

const styles = () => ({
  root: {
    boxSizing: "border-box",
    margin: "0",
    padding: "0"
  },
  textInput: {
    textAlign: "center"
  },
  test: {
    fontSize: "3rem"
  }
});

const CampaignForm = props => {
  const { classes } = props;
  const [selectedFile, setSelectedFile] = useState();
  const [isFileSelected, setIsFileSelected] = useState(false);

  const handleClear = event => {
    setIsFileSelected(false);
    setSelectedFile("");
    console.log(selectedFile.name);
  };

  const handleFileSelection = event => {
    setSelectedFile(event.target.files[0]);
    setIsFileSelected(true);
  };

  return (
    <div className={classes.root}>
      <h1 className={classes.textInput}>Text Campaign</h1>
      <div className={classes.textInput}>
        <label htmlFor='upload-csv'>
          <input
            style={{ display: "none" }}
            id='upload-csv'
            disabled={isFileSelected}
            name='upload-csv'
            type='file'
            onChange={handleFileSelection}
          />
          <Fab
            color='primary'
            size='small'
            disabled={isFileSelected}
            component='span'
            aria-label='add'
            variant='extended'>
            <AddIcon /> Add CSV
          </Fab>
        </label>
        <br />
        {isFileSelected ? (
          <div>
            <br />
            <button onClick={handleClear}>clear</button>
            <p>{selectedFile.name}</p>
          </div>
        ) : (
          <p>No file added</p>
        )}
      </div>
    </div>
  );
};
CampaignForm.propTypes = { classes: PropTypes.object.isRequired };
export default withStyles(styles)(CampaignForm);

enter image description here

你必须在 handleClear 函数中做,我猜 setSelectedFile(event.target.files[0]); 是 json 对象而不是字符串,

setSelectedFile({});

因为你正在 setSelectedFile(""); 设置字符串,字符串没有 .name 只有 json 有

<p>{selectedFile.name}</p>

所以 "".name 名称将是 undefined,这是正确的,您的解决方法是这样,希望它能有所帮助

  const handleClear = event => {
    setIsFileSelected(false);
    setSelectedFile({});
    console.log(selectedFile.name);
  };

首先你需要将默认的null值设置为selectedFile状态。

const [selectedFile, setSelectedFile] = useState(null);

然后,在 handleClear 函数中设置,

setSelectedFile(null);

最后的条件应该是

{isFileSelected ? (
          <div>
            <br />
            <button onClick={handleClear}>clear</button>
            <p>{selectedFile.name}</p>
          </div>
        ) : (
          selectedFile === null && <p>No file added</p>
        )}

[可选]: 默认文件 select 事件不会再次 select 相同的文件,因此如果您需要允许用户 select 相同的文件然后在输入标签中添加以下 属性 :

onClick={(event) => {
              event.target.value = null;
            }}