【问题标题】:Parsing different inputs in multi-part forms - React form以多部分形式解析不同的输入 - React 形式
【发布时间】:2021-04-20 21:26:54
【问题描述】:

我目前在我构建的表单组件中遇到错误,我认为这与我在表单中设置不同类型的输入的方式有关。我有一种方法可以设置我认为会导致我尝试提交的文件出现问题的表单状态。

const ArticleForm = (props) => {

    const user = useSelector(state => state.user);

    const fields = useSelector(state => state.fields);

    const { articleTypeList } = fields;

    // state for the current field value
    const [article, setArticle] = useState({
        articleTitle: ``,
        articleTypeID: ``,
        articleContent: ``,
        userID: ``,
        **photos: null,**
        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) => {
        setArticle({
            // override the changed property and keep the rest
            ...article,
            [property]: e.target.value,
        });**
    }

    const handleChangeInt = (property) => (e) => {
        setArticle({
            // override the changed property and keep the rest
            ...article,
            [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(requireFieldData());
    }, []);

    function handleSubmitArticle(e: React.FormEvent<HTMLFormElement>) {
        e.preventDefault();
        const formData = new FormData();
        formData.append("articleTitle", article.articleTitle);
        formData.append("articleContent", article.articleContent);
        formData.append("userID", article.userID);
        formData.append("articleTypeID", article.articleTypeID);
        formData.append("photos", article.photos);
        axios.post("http://localhost:5002/api/divelog/createdivelog", formData);
    }

    const classes = useStyles;

return (
    <div>

    <AppBar title="Enter your dive details"></AppBar>
    <form
        class="mt-4"
        id="articleForm"
        method="POST"
        enctype="multipart/form-data"
        onSubmit={handleSubmitArticle}>
        <>
            <Grid container spacing={3}
                  direction="row"
                  justify="center"
                  alignItems="center">
                <Grid item xs={10}>
                     <TextField
                      placeholder="Article-Title"
                      label="Article Title"
                      name="articleTitle"
                      margin="normal"
                      value={article.articleTitle}
                      onChange={handleChange("articleTitle")}
                      fullWidth/>
                </Grid>
                <Grid item xs={5}>
                    <FormControl className={classes.formControl}>
                        <TextField
                            placeholder="Author-User-Number"
                            label="AuthorUserNumber"
                            // defaultValue={props.user.userID}
                            margin="normal"
                            value={props.user.userID}
                            onChange={handleChangeInt("userID")}
                            fullWidth/>
                    </FormControl>
                </Grid>
                <Grid item xs={5}>
                    <FormControl className={classes.formControl}>
                        <PopulateDropdown
                            dataList={articleTypeList}
                            titleProperty={"articleType"}
                            valueProperty={"articleTypeID"}
                            label="Article Type"
                            placeholder="Select article type"
                            value={article.articleTypeID}
                            onChange={handleChangeInt("articleTypeID")}/>
                    </FormControl>
                </Grid>
                <Grid item xs={10}>
                    <FormControl fullWidth className={classes.formControl}>
                        <TextField
                            placeholder="Article Content"
                            label="ArticleContent"
                            name="articleContent"
                            value={article.articleContent}
                            onChange={handleChange("articleContent")}
                            multiline
                            rowsMax={6}
                            fullWidth/>
                    </FormControl>
                </Grid>
                <br />
                <Grid item xs={10}>
                    <div class="form-control">
                        <label for="photos">Photo Upload</label>
                        <input
                            type="file"
                            name="photos"
                            id="photos"
                            value={article.photos}
                            onChange={handleChange("photos")}/>
                    </div>
                </Grid>
                <br />
                <Grid item xs={8} md={6}>
                    <Button variant="primary" type="submit">
                        Submit</Button>
                </Grid>
            </Grid>
    </>
    </form>
    </div>
)
}

我认为这是与此错误相关的控制台错误消息。

错误信息

(node:32864) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'filename' of undefined
    at exports.createDiveLog (...roject\SustainableScuba\backend\controllers
\diveLog.controller.js:15:47)
    at Layer.handle [as handle_request] (...ess\lib\router\layer.js:95:5)
    at next (...vproject\SustainableScuba\backend\node_modules\express\lib\rou
ter\route.js:137:13)
    at Array.<anonymous> (...roject\SustainableScuba\backend\node_modules\mu
lter\lib\make-middleware.js:53:37)
    at listener (...ect\SustainableScuba\backend\node_modules\on-finished
\index.js:169:15)
    at onFinish (...oject\SustainableScuba\backend\node_modules\on-finished
\index.js:100:5)
    at callback (...evproject\SustainableScuba\backend\node_modules\ee-first\in
dex.js:55:10)
    at IncomingMessage.onevent (...project\SustainableScuba\backend\node_modu
les\ee-first\index.js:93:5)
    at IncomingMessage.emit (events.js:215:7)
    at endReadableNT (_stream_readable.js:1183:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)
(node:32864) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:32864) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'filename' of undefined
    at exports.createDiveLog (...oject\SustainableScuba\backend\controllers
\diveLog.controller.js:15:47)
    at Layer.handle [as handle_request] (...roject\SustainableScuba\backend\
node_modules\express\lib\router\layer.js:95:5)

【问题讨论】:

    标签: node.js reactjs multipartform-data


    【解决方案1】:
    <TextField
      placeholder="Article-Title"
      label="Article Title"
      name="articleTitle"
      margin="normal"
      value={article.articleTitle}
      onChange={handleChange("articleTitle")}
      fullWidth/>
    

    这里的onChange应该是错误的,不要返回新函数,而是尝试将属性绑定到句柄更改函数

    正确的代码写法是

    onChange={handleChange.bind(null, "articleTitle")}
    

    而你的handleChange函数会变成这样

    const handleChange = (property, e) => {
        setArticle({
            // override the changed property and keep the rest
            ...article,
            [property]: e.target.value,
        });
    }
    

    【讨论】:

    • 我已经尝试过了,但现在我的提交按钮没有激活。我知道的问题是,提交表单时,文件显示为未定义。所以肯定是跟useState方法和设置值有关。
    • 我相信错误来自文件/照片的定义方式。单击提交时,后端会抛出一条错误消息,指出文件未定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多