Не удается отправить URL загруженного изображения из firebase в другие компоненты в хуках реакции - PullRequest
0 голосов
/ 27 мая 2020

Я не могу отправить URL-адрес загруженного изображения из хранилища firebase в другой компонент с помощью перехватчиков реакции. Кто-нибудь может мне помочь? Я новичок в реакции и работаю над этой частью кода около 2 недель, и у меня не было никакого прогресса, это меня действительно раздражает.

Это основной компонент, в который должен поступать URL-адрес изображения для его рендеринга

import React, { useState, useEffect} from "react";
import firebase from "firebase";
import Uploader from "./uploader";

function EditorBlog() {
    const [title, setTitle] = useState("");
    const [text, setText] = useState("");
    const [category, setCategory] = useState("");
    const [url , setUrl]= useState("");
    const [items, setItems] = useState([]);

    const onSubmit = (data) => {

        data.preventDefault();
        setItems([...items, {title, text, category , url} ]);
        firebase
            .firestore()
            .collection('blogContent')
            .add({
                title,
                category,
                text,
                url
                // file
            })
            .then(()=>{
                setTitle('')
                setCategory('')
                setText('')
                setUrl('')
            });
    };


    return (
        <div>

            <form onSubmit={onSubmit} className="col-md-6 mx-auto mt-5">
                <div className="form-group">
                    <label htmlFor="Title">Blog Title</label>
                    <input
                        type="text"
                        name="title"
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                        className="form-control"
                        id="Title"
                        placeholder="Arnold Schwarzneiger"
                    />
                </div>
                <Uploader/>
                <div className="form-group">
                    <label htmlFor="categorySelect">Select Category</label>
                    <select className="form-control" value={category} onChange={e => setCategory(e.target.value)} name="category" id="categorySelect">
                        <option>Nutrition</option>
                        <option>Fitness</option>
                        <option>Recipes</option>
                        <option>Succesfull Stories</option>
                        <option>Other</option>
                    </select>
                </div>
                <div className="form-group">
                    <label htmlFor="blogText">Blog Text</label>
                    <textarea
                        className="form-control"
                        name="text"
                        id="blogText"
                        rows="3"
                        value={text}
                        onChange={(e) => setText(e.target.value)}
                    ></textarea>
                </div>
                <button
                    type="submit"
                    className="btn btn-primary offset-5"
                    onClick={onSubmit}
                >
                    Save
                </button>
            </form>

            <div className="mt-5">
                {
                    items.map((item, index) => (
                        <div className="row bg-dark mx-auto ">
                        <div key={item.id} className="col-md-6 blogs_content mx-auto mt-5 " >
                            <div className="mblog_imgtop "><p>Beginner</p></div>
                            <img className="img-fluid editor_img " src={item.url} alt=""/>
                            <div className="col-md-12 rblog_txt text-center mx-auto">
                                <h6 className="mblog_category mx-auto m-4">{item.category}</h6>
                                <h2 className="blogs_title col-md-10 mx-auto">{item.title}</h2>
                                <div className="mt-5 mblog_innertxt col-md-11 mx-auto">{item.text}</div>
                                <div className="readm mt-5"><i>READ MORE</i></div>
                            </div>

                        </div>
                        </div>
                    ))
                }
            </div>
        </div>
    );
}
export default EditorBlog;

это мой второй компонент, в котором URL-адрес загруженного изображения должен быть отправлен в основной компонент

import React, {useState} from "react";
import {storage} from "../../firebaseConfig";
import firebase from "firebase";


export default function Uploader() {
    const [image , setImage]= useState(null);
    const [url , setURL]= useState("");
    const [imgURL, setImgURL] = useState('');
    const [progress , setProgress]= useState(0);
    const [error , setError]= useState("");


    const handleChange =e =>{
    const file = e.target.files[0];

    if (file){
        const fileType= file["type"];
        const validFileType= ["image/gif", "image/png", "image/jpg", "image/jpeg"];
        if (validFileType.includes(fileType)){
            setError("");
            setImage(file);
        }else setError("Siz rasm kiritmadingiz");
    }else {
        setError("Iltimos faylni tanlang");
    }
    };


    const handleUpload = props=>{

        if (image){
            const uploadTask =storage.ref(`images/${image.name}`).put(image);
            uploadTask.on(
                "state_changed",
                snapshot =>{
                    const progress = Math.round(
                        (snapshot.bytesTransferred/snapshot.totalBytes)*100
                    );
                    setProgress(progress);
                },
                error =>{
                    setError(error);
                },
                ()=>{
                    storage.ref("images").child(image.name).getDownloadURL().then(url=>{
                        setURL(url);
                        console.log(url);
                        firebase
                            .firestore()
                            .collection('images')
                            .add({
                                url
                            })
                            .then(()=>{
                                setURL('')
                            });

                        setProgress(0);
                    });


                }
            )

        }else setError("Xatolik Iltimos rasmni yuklang")
    };
    return(
        <div>
            <form >
                <div className="form-group" >
                    <input type="file" className="form-control" onChange={handleChange} />
                    <button type="button" className="btn btn-primary btn-block" onClick={handleUpload}>Upload</button>
                </div>
            </form >
            <div>
                {progress > 0 ? <progress style={{marginLeft: "15px"}} value={progress} max="100"/> :""}
            </div>
            <div style={{height : "100px", marginLeft: "15px", fontWeight: "600"}}>
                <p style={{color: "red"}}>{error}</p>
            </div>
            <img src={url || 'http://via.placeholder.com/400x300'} alt="Uploaded images" height="300" width="650"/>
        </div>
    )
}

1 Ответ

0 голосов
/ 27 мая 2020

Используя обратный вызов, ваш EditorBlog компонент может сообщить компоненту Uploader, что делать после завершения загрузки.

Другими словами, EditorBlog передает функцию под названием «onComplete» как опору для Загрузчик. Когда загрузка завершена, Uploader вызывает эту функцию с URL-адресом в качестве аргумента.

EditorBlog

export default function EditorBlog() {
  const [url , setUrl] = useState(null);

  // ...

  const handleCompletedUpload = (url) => {
    setUrl(url);
  }

  return (
    // ...
    <div>
      <Uploader onComplete={handleCompletedUpload} />
      <img src={url || 'http://via.placeholder.com/400x300'} alt="Uploaded images" height="300" width="650" />
    </div>
    // ...
  );
}

Загрузчик:

export default function Uploader({ onComplete }) {

// ...

  uploadTask.on(
    "state_changed", (snapshot) => {
      // ... progress update
    },
    (error) => {
      // ... error
    },
    () => {
      // Success. Get the URL and call the prop onComplete
      uploadTask.snapshot.ref.getDownloadURL().then(url => {
        onComplete(url); // Call the callback provided as a prop
      });
    })

// ...
}

Кстати: обратите внимание, как вы можете получить ссылку на файл напрямую из uploadTask: uploadTask.snapshot.ref.getDownloadURL(). Таким образом, вам не нужно создавать новую ссылку вручную, например storage.ref("images").child(image.name).getDownloadURL().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...