首页 > 解决方案 > UseState 方法在表单中将文件传递到后端

问题描述

我在前端创建了一个表单,用于将多部分数据传递到具有文本、int 和文件数据的后端。当我发布到后端时,它目前无法识别文件,因为我认为它没有正确地通过提交方法。

我需要不同的文件 setState 方法吗?它目前在 useState 方法中设置为未定义,我认为这是传递给后端的内容。当我测试它时,API 在 Postman 中工作以存储 url,但无论以何种方式传递它都会导致“网络错误”。我应该在 set 方法中将其定义为什么?我也尝试过 null 和 `` 但我遇到了类似的错误。

错误信息

(node:40516) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'filename' of undefined
    at exports.createMarineLife (C:\Users\James Greene\WebstormProjects\softwaredevproject\SustainableScuba\backend\con
trollers\marineLife.controller.js:7:47)
// state for the current field value
    const [life, setLife] = useState({
        marineTypeID: null,
        marineName: ``,
        marineDescription: ``,
        photos: undefined,
        error: ``
    });

    // all onChange functions do the exact same thing, so you only need one
    // pass to a component like onChange={handleChange('typeID')}
    const handleChange = (property) => (e) => {
        setLife({
            // override the changed property and keep the rest
            ...life,
            [property]: e.target.value,
        });
    }

    const handleChangeInt = (property) => (e) => {
        setLife({
            // override the changed property and keep the rest
            ...life,
            [property]: parseInt(e.target.value),
        });
    }

    // get access to dispatch
    const dispatch = useDispatch();

    // useEffect with an empty dependency array is the same as componentDidMount
    useEffect(() => {
        // dispatch the action to load fields for each field type
        // once loaded, the changes will be reflected in the fields variable from the useSelector
        Object.keys(fields).forEach(name => dispatch(requireFieldData(name)));
    }, []); // <-- empty array

    function handleSubmitMarineLife(e: React.FormEvent<HTMLFormElement>) {
        e.preventDefault();
        const formData = new FormData();
        formData.append("marineTypeID", life.marineTypeID);
        formData.append("marineName", life.marineName);
        formData.append("marineDescription", life.marineDescription);
        formData.append("photos", file);
        axios.post("http://localhost:5002/api/marinelife/createmarinelife", formData);
    }

    const classes = useStyles;

    return (
        <>
        <form className="marineLifeForm" method="POST" encType="multipart/form-data" onSubmit={handleSubmitMarineLife}>
                <Grid container spacing={3}
                      direction="row"
                      justify="center"
                      alignItems="center">
                    <Grid item xs={4}>
                        <FormControl className={classes.formControl}>
                            <PopulateDropdown
                                dataList={marineTypeList}
                                titleProperty={"marineType"}
                                valueProperty={"marineTypeID"}
                                name="marineType"
                                label="Select marine type"
                                value={life.marineTypeID}
                                onChange={handleChangeInt("marineTypeID")}/>
                        </FormControl>
                    </Grid>
                    <br />
                    <Grid item xs={4}>
                        <FormControl className={classes.formControl}>
                            <TextField
                                id="standard-adornment-amount"
                                label="MarineName"
                                value={life.marineName}
                                onChange={handleChange("marineName")}/>
                        </FormControl>
                    </Grid>
                    <br />
                    <Grid item xs={10}>
                        <FormControl fullWidth className={classes.margin}>
                            <TextField
                                id="standard-adornment-amount"
                                label="Description"
                                value={life.marineLifeDescription}
                                onChange={handleChange("marineLifeDescription")}
                                multiline
                                rowsMax={6}/>
                        </FormControl>
                    </Grid>
                    <br />
                    <Grid item xs={10}>
                        <FormControl fullWidth className={classes.margin}>
                            <label for="photos">Photo Upload</label>
                            <input
                                type="file"
                                name="photos"
                                id="photos"
                                value={life.photos}
                                onChange={handleChange("photos")}/>
                        </FormControl>
                    </Grid>
                    <br />
                    <Grid item xs={3}>
                        <Button variant="primary" type="submit">
                            Submit</Button>
                        <br />
                    </Grid>
                </Grid>
        </form>

标签: node.jsreactjsexpress

解决方案


推荐阅读