Ant Design 和 React 问题
AntDesign and React issue
如何使用 AntDesign 从一个组件获取值到另一个组件?
我有组件调用 CreateProduct 导入另一个 AntDesign 组件调用 AddImage
AddImage 将图片上传到 Cloudinary 并获取上传图片的 url,这工作正常但 CreateProduct 不更新值
我假设使用 useEffect 应该可以解决问题,但不确定如何实现
这是CreateProduct组件
import React, { useState, useEffect } from 'react';
import {
Form,
Button,
Input,
Select,
message,
Alert,
notification,
} from 'antd';
import { AddImage } from './AddImage.js';
import { createProduct } from '../../services/Products';
function CreateProductForm({ history }) {
const [img, setImg] = useState(null);
const [error, setError] = useState(null);
const openNotification = (placement, coincidencias) => {
notification.info({
message: `Coincidences found ${coincidencias}`,
description: `We have found ${coincidencias} wishes that may be coincidences of your product`,
placement,
});
};
async function handleFormSubmit(values) {
let send = true;
console.log(img);
// HERE I need to update img to ut in the values and send it to the Db
// values.image = img; /
//mensajes de campos vacios en form
Object.entries(values).map((val) => {
if (val[1] === undefined) {
message.error(`Add ${val[0].toUpperCase()} field is empty`);
send = false;
}
if (val[0] === 'price') {
setError(
'All the fields must be filled and the price must have numbers,not letters!'
);
let valor = Number(val[1]);
if (typeof valor !== 'number') {
send = false;
}
}
});
if (send) {
let { data } = await createProduct(values);
if (data.wishCoincidences.length > 0) {
openNotification('bottomRight', data.wishCoincidences.length);
} //mensajes de coincidencias
history.push('/MyProducts');
message.success(`${data.name} created`);
}
}
return (
<>
<Form layout="vertical" onFinish={handleFormSubmit}>
<h1>Create your product!</h1>
{error && <Alert message={error} type="error" />}
<Form.Item name="name" label="Title:">
<Input />
</Form.Item>
<Form.Item name="description" label="Description:">
<Input />
</Form.Item>
<Form.Item name="price" label="Price:">
<Input />
</Form.Item>
<Form.Item name="image" label="Image:">
{/* This returns img, which is an url, how do I get it?*/}
<AddImage />
{img & img ? img : 'not reading img'}
</Form.Item>
<Form.Item name="category" label="category:">
<Select initialvalue="" style={{ width: '20%' }}>
<Select.Option value="books">Books</Select.Option>
<Select.Option value="electronics">Electronics</Select.Option>
<Select.Option value="clothes">Clothes</Select.Option>
<Select.Option value="other">Other</Select.Option>
</Select>
</Form.Item>
<Button type="primary" block size="middle" htmlType="submit">
Create
</Button>
</Form>
</>
);
}
export default CreateProductForm;
这是AddImage组件
import { Upload } from 'antd';
import React, { useState } from 'react';
import axios from 'axios';
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
const cloudinaryAPI =
'https://api.cloudinary.com/**********************/upload';
export const AddImage = () => {
const [img, setImg] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
async function handleUploadFile(file) {
try {
setLoading(true);
const data = new FormData();
//esto sube a el archivo a cloudinary
data.append('file', file);
data.append('upload_preset', 'uploadfilestiendaDeGarage');
//esto manda al backend? me manda CORS
const {
data: { secure_url },
} = await axios.post(cloudinaryAPI, data);
setImg(secure_url);
setLoading(false);
} catch (e) {
console.dir(e.response.data.message);
setError(e.response.data.message);
}
}
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<>
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
beforeUpload={handleUploadFile}
// action={() => alert(img)}
>
{img ? (
<img src={img} alt="pic" style={{ width: '50%' }} />
) : (
uploadButton
)}
</Upload>
</>
);
};
您可以在我想要实现此功能的地方找到该应用程序的实时版本here
对于图像状态,您在 CreateProduct
和 AddImage
组件中具有相同的名称,因此请尝试更改 CreateProduct
中的状态名称,如下所示:-
const [imgUrl, setImgUrl] = useState(null);
将 setImgUrl
作为 AddImage
组件中的 prop 传递
<AddImage setImgUrl={(url) => setImgUrl(url)}/>
在 AddImage
中提取 setImgUrl
并在 handleUploadFile
中使用,如下所示:-
export const AddImage = ({setImgUrl}) => {
const [img, setImg] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
async function handleUploadFile(file) {
try {
setLoading(true);
const data = new FormData();
//esto sube a el archivo a cloudinary
data.append('file', file);
data.append('upload_preset', 'uploadfilestiendaDeGarage');
//esto manda al backend? me manda CORS
const {
data: { secure_url },
} = await axios.post(cloudinaryAPI, data);
setImg(secure_url);
setImgUrl(secure_url); // use function here to set image url
setLoading(false);
} catch (e) {
console.dir(e.response.data.message);
setError(e.response.data.message);
}
}
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<>
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
beforeUpload={handleUploadFile}
// action={() => alert(img)}
>
{img ? (
<img src={img} alt="pic" style={{ width: '50%' }} />
) : (
uploadButton
)}
</Upload>
</>
);
};
所以现在 imgUrl
将有图像 url,您可以在 CreateProduct
组件中使用它。
如何使用 AntDesign 从一个组件获取值到另一个组件?
我有组件调用 CreateProduct 导入另一个 AntDesign 组件调用 AddImage
AddImage 将图片上传到 Cloudinary 并获取上传图片的 url,这工作正常但 CreateProduct 不更新值
我假设使用 useEffect 应该可以解决问题,但不确定如何实现
这是CreateProduct组件
import React, { useState, useEffect } from 'react';
import {
Form,
Button,
Input,
Select,
message,
Alert,
notification,
} from 'antd';
import { AddImage } from './AddImage.js';
import { createProduct } from '../../services/Products';
function CreateProductForm({ history }) {
const [img, setImg] = useState(null);
const [error, setError] = useState(null);
const openNotification = (placement, coincidencias) => {
notification.info({
message: `Coincidences found ${coincidencias}`,
description: `We have found ${coincidencias} wishes that may be coincidences of your product`,
placement,
});
};
async function handleFormSubmit(values) {
let send = true;
console.log(img);
// HERE I need to update img to ut in the values and send it to the Db
// values.image = img; /
//mensajes de campos vacios en form
Object.entries(values).map((val) => {
if (val[1] === undefined) {
message.error(`Add ${val[0].toUpperCase()} field is empty`);
send = false;
}
if (val[0] === 'price') {
setError(
'All the fields must be filled and the price must have numbers,not letters!'
);
let valor = Number(val[1]);
if (typeof valor !== 'number') {
send = false;
}
}
});
if (send) {
let { data } = await createProduct(values);
if (data.wishCoincidences.length > 0) {
openNotification('bottomRight', data.wishCoincidences.length);
} //mensajes de coincidencias
history.push('/MyProducts');
message.success(`${data.name} created`);
}
}
return (
<>
<Form layout="vertical" onFinish={handleFormSubmit}>
<h1>Create your product!</h1>
{error && <Alert message={error} type="error" />}
<Form.Item name="name" label="Title:">
<Input />
</Form.Item>
<Form.Item name="description" label="Description:">
<Input />
</Form.Item>
<Form.Item name="price" label="Price:">
<Input />
</Form.Item>
<Form.Item name="image" label="Image:">
{/* This returns img, which is an url, how do I get it?*/}
<AddImage />
{img & img ? img : 'not reading img'}
</Form.Item>
<Form.Item name="category" label="category:">
<Select initialvalue="" style={{ width: '20%' }}>
<Select.Option value="books">Books</Select.Option>
<Select.Option value="electronics">Electronics</Select.Option>
<Select.Option value="clothes">Clothes</Select.Option>
<Select.Option value="other">Other</Select.Option>
</Select>
</Form.Item>
<Button type="primary" block size="middle" htmlType="submit">
Create
</Button>
</Form>
</>
);
}
export default CreateProductForm;
这是AddImage组件
import { Upload } from 'antd';
import React, { useState } from 'react';
import axios from 'axios';
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
const cloudinaryAPI =
'https://api.cloudinary.com/**********************/upload';
export const AddImage = () => {
const [img, setImg] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
async function handleUploadFile(file) {
try {
setLoading(true);
const data = new FormData();
//esto sube a el archivo a cloudinary
data.append('file', file);
data.append('upload_preset', 'uploadfilestiendaDeGarage');
//esto manda al backend? me manda CORS
const {
data: { secure_url },
} = await axios.post(cloudinaryAPI, data);
setImg(secure_url);
setLoading(false);
} catch (e) {
console.dir(e.response.data.message);
setError(e.response.data.message);
}
}
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<>
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
beforeUpload={handleUploadFile}
// action={() => alert(img)}
>
{img ? (
<img src={img} alt="pic" style={{ width: '50%' }} />
) : (
uploadButton
)}
</Upload>
</>
);
};
您可以在我想要实现此功能的地方找到该应用程序的实时版本here
对于图像状态,您在 CreateProduct
和 AddImage
组件中具有相同的名称,因此请尝试更改 CreateProduct
中的状态名称,如下所示:-
const [imgUrl, setImgUrl] = useState(null);
将 setImgUrl
作为 AddImage
组件中的 prop 传递
<AddImage setImgUrl={(url) => setImgUrl(url)}/>
在 AddImage
中提取 setImgUrl
并在 handleUploadFile
中使用,如下所示:-
export const AddImage = ({setImgUrl}) => {
const [img, setImg] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
async function handleUploadFile(file) {
try {
setLoading(true);
const data = new FormData();
//esto sube a el archivo a cloudinary
data.append('file', file);
data.append('upload_preset', 'uploadfilestiendaDeGarage');
//esto manda al backend? me manda CORS
const {
data: { secure_url },
} = await axios.post(cloudinaryAPI, data);
setImg(secure_url);
setImgUrl(secure_url); // use function here to set image url
setLoading(false);
} catch (e) {
console.dir(e.response.data.message);
setError(e.response.data.message);
}
}
const uploadButton = (
<div>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
return (
<>
<Upload
name="avatar"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
beforeUpload={handleUploadFile}
// action={() => alert(img)}
>
{img ? (
<img src={img} alt="pic" style={{ width: '50%' }} />
) : (
uploadButton
)}
</Upload>
</>
);
};
所以现在 imgUrl
将有图像 url,您可以在 CreateProduct
组件中使用它。