你好,我在react + graphql + node和mongod中有一个项目,而且我尝试将图像上传到我的应用程序中的文件夹中,并且保存文件后重新加载应用程序时遇到问题。在执行上载过程时,我尝试管理组件中的本地状态,但是由于重新加载应用程序,我的本地变量更改为初始状态,并且无法显示我的文件的预览。我的目标是预览img上传。
我认为我的问题出在解析器的storeUpload函数中
代码。
API -----------解析器------
const Product = require('../models/Product');
const { createWriteStream } = require("fs");
async function createProduct(root, args) {
console.log(args.file)
let product = await new Product(args)
console.log(product);
product.save()
if(args.file){
const { stream, filename, mimetype, encoding } = await args.file;
await storeUpload({ stream, product });
}
return product
}
const storeUpload = ({ stream, product }) =>
new Promise((resolve, reject) =>
stream
.pipe(createWriteStream("./images/" + product._id +".png"))
.on("finish", () => resolve())
.on("error", reject)
);
module.exports = {
createProduct
}
---反应---组件----
import React , { useState, useEffect } from 'react'
import {Grid} from '@material-ui/core'
import { Mutation } from "react-apollo"
import {PRODUCTOS} from './Productos'
import gql from "graphql-tag";
import {StyleStateConsumer} from '../../../Context/StylesStateContext'
/** @jsx jsx */
import { jsx, css } from '@emotion/core'
const borde = css({
borderStyle: 'solid'
})
const contendorForm = css({
borderRadius: 15,
backgroundColor: '#ffffe6'
},borde)
const itemsForm = css({
padding: 15
})
const inputStyle = css({
borderRadius: 5,
padding: 3
})
const ADD_PRODUCT = gql`
mutation CreateProduct($title: String, $price: Float, $file: Upload) {
createProduct(title: $title, price: $price, file: $file) {
_id
title
}
}
`;
const CrearProducto = props =>{
const [titleInput, settitleInput] = useState('')
const [priceInput, setpriceInput] = useState(0)
const [fileInput, setfileInput] = useState('')
const [imgName, setimgName] = useState('default')
const handleChange = e =>{
const {name, type, value} = e.target
if(name === 'titleInput'){settitleInput(value)}
if(name === 'priceInput'){setpriceInput(parseFloat(value))}
}
const imgUpdate = (imgConxt) => {
setimgName(imgConxt)
}
useEffect( imgUpdate )
const handleFile = (obj) =>{console.log(obj)}
return(
<StyleStateConsumer>
{({imagenID, updateHState})=>(
<Grid container css={borde}
direction="row"
justify="center"
alignItems="center">
<Grid item css={contendorForm}>
{imgUpdate(imagenID)}
<Grid container
direction="row"
justify="center"
alignItems="center"><Grid item >Crear Producto:</Grid>
</Grid>
<Grid container>
<Mutation mutation={ADD_PRODUCT} refetchQueries={[{
query: PRODUCTOS
}]}>
{(createProduct, { data, loading })=>{
if (loading) return <div>Loading...</div>
console.log(data)
return(
<div>
<form css={itemsForm}
onSubmit={ (e) => {
e.preventDefault()
createProduct({
variables: {
title: titleInput,
price: priceInput,
file: fileInput
}
})
//
updateHState(res.data.createProduct._id
=== undefined ? '' :
res.data.createProduct._id)
settitleInput('')
setpriceInput(0)
//
console.log(res.data.createProduct._id)
}}>
<Grid item>
<input
css={inputStyle}
type="file"
onChange={({
target: { validity, files:
[file] } }) => validity.valid &&
setfileInput(file)
}
/>
</Grid>
<Grid item>
<label>
Titulo:
</label>
</Grid>
<Grid item>
<input css={inputStyle} type="text"
name="titleInput"
placeholder="Ingresar Título"
value={titleInput}
onChange={handleChange}
/>
</Grid>
<Grid item>
<label>
Precio:
</label>
</Grid>
<Grid item>
<input css={inputStyle} type="number"
name="priceInput"
placeholder="Ingresar Precio"
value={priceInput}
onChange={handleChange}/>
</Grid>
<Grid item>
<input type="submit" name="Crear"/>
</Grid>
</form>
</div>
)
}}
</Mutation>
</Grid>
</Grid>
<Grid item css={[borde,
{
backgroundImage: `url('${require('../../../../../back-
end/images/' + imgName + '.png')}')`,
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
height: 300,
width: 300}]}>
</Grid>
</Grid>
)}
</StyleStateConsumer>
)
}
export default CrearProducto
答案 0 :(得分:0)
好吧,首先,您要传递给useEffect的imgUpdate
函数永远不会获得其imgConxt
参数。这个钩子只调用一个空参数函数来在渲染后执行一堆代码。
对于您的主要问题,控制台中是否有任何警告或错误?
一种快速但肮脏的解决方法是更改您的<input type='submit'>
来键入button并在其中的onClick
处理程序中进行逻辑处理。