简体   繁体   English

AntDesign 和 React 问题

[英]AntDesign and React issue

How do I obtain a value from one component to another using AntDesign?如何使用 AntDesign 从一个组件到另一个组件获取值?

I have component call CreateProduct which imports another AntDesign component call AddImage我有组件调用CreateProduct导入另一个 AntDesign 组件调用AddImage

AddImage uploads a picture to Cloudinary and obtains the url of the pic uploaded, this works fine but the CreateProduct don't update the value AddImage 将图片上传到 Cloudinary 并获取上传图片的 url,这工作正常,但CreateProduct不更新值用作预览的图像的 url 其 src

I have the hypothesis that using useEffect should solve the problem but not sure how to implement我假设使用 useEffect 应该可以解决问题,但不确定如何实现

This is the CreateProduct component这是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;

This is the AddImage component这是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>
    </>
  );
};

You can se a live version of the app where I want to implement this here您可以在此处查看我想要实现此功能的应用程序的实时版本

For image state you have same name in CreateProduct and AddImage component so try to change state name in CreateProduct like below:-对于图像 state,您在CreateProductAddImage组件中具有相同的名称,因此请尝试在CreateProduct中更改 state 名称,如下所示:-

const [imgUrl, setImgUrl] = useState(null);

Pass setImgUrl as prop in AddImage componentAddImage组件setImgUrl作为 prop 传递

<AddImage setImgUrl={(url) => setImgUrl(url)}/>

Extract setImgUrl in AddImage and use in handleUploadFile like below:-handleUploadFile中提取setImgUrl并在AddImage中使用,如下所示:-

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>
    </>
  );
};

So now imgUrl will have image url and you can use it in CreateProduct component.所以现在imgUrl将有图像 url 并且您可以在CreateProduct组件中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM