Кнопка не отправляет идентификатор функции, если страница не перезагружается - PullRequest
0 голосов
/ 11 апреля 2020

У меня проблемы с доступом к идентификатору кнопки непосредственно после ее создания с помощью функции .map () ....

Вот нижний предел ... Я постараюсь сделать это проще -

Пользователь вводит URL-адрес YouTube во вход.

Функция onClick handleAddVideo () выполняет две функции. Он извлекает идентификатор видео YouTube из URL-адреса и сохраняет этот URL-адрес в состоянии, называемом videoLinks.

В моем рендере я сопоставляю массив с состоянием videoLinks, и он автоматически встраивает их в профиль пользователя с помощью кнопки для удаления видео.

Кнопка удаления имеет функцию onClick, которая использует идентификатор кнопки (такой же, как идентификатор видео), чтобы найти и удалить видео из состояния.

Это работает, за исключением одной проблемы ... страница должна быть перезагружена, чтобы кнопка отправила идентификатор функции удаления. Если пользователь отправляет ссылку и публикует видео, не обновляя страницу, он выдает TypeError: Cannot read свойство 'id' из null. Если страница перезагружена - все работает нормально. Спасибо за вашу помощь!

    import React, { useState, useEffect } from 'react';
import { useAuth0 } from "../../../react-auth0-spa";
import { Input, Card, Button, CardTitle
} from 'reactstrap';

let saveLinks = true

export default function VideoCard(props) {
    const [ linkHolder, setVideoLinkHolder ] = useState('')
    const [ videoLinks, setVideoLinks ] = useState([]);
    const { getTokenSilently } = useAuth0();

    useEffect(() => {
        getOldVideoLinks();
    }, [])

    useEffect(() => {
        if(saveLinks){
            setTimeout(() => {
                saveLinks = false
            },300)
        }else {
            saveVideoLinks();
        }
    }, [videoLinks])

    const getOldVideoLinks = async () => {
        const token = await getTokenSilently();

        try {
            const response = await fetch(`/api/autoquotegenerators/${props._id}`, {
                headers: {
                    Authorization: `bearer ${token}`,
                    "Content-Type": "application/json; charset=UTF-8",
                }
            });
            const responseData = await response.json()
            setVideoLinks(responseData.youtube)
        } catch (error) {
            console.log(error)
        }
    }

    const handleAddVideoLink = (e) => {
        setVideoLinkHolder(e.target.value);

    }

    const handleAddVideo = () => {
        if(videoLinks.length < 4){
            if(linkHolder){
                var regExp = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
                var match = linkHolder.match(regExp);
                if (match && match[2].length == 11) {
                    console.log(match[2])
                    return setVideoLinks((videoLinks) => [...videoLinks, match[2]]);
                } else {
                    alert('Sorry! Please use a valid Youtube URL.')
                }
            }else {
                alert('Copy and Paste a Youtube Link Before Submitting!')
            }
        }else {
            alert('You have reached the maximum number of videos for this band.')
        }

    }

    const saveVideoLinks = async () => {
        const token = await getTokenSilently();
        try {
            const response = await fetch(`/api/autoquotegenerators/${props._id}`, {
                method: 'PUT',
                headers: {
                    "Authorization": `Bearer ${token}`,
                    "Content-Type": "application/json; charset=UTF-8",
                },
                body: JSON.stringify({youtube: videoLinks})
            })
            const responseData = response.json()
        } catch (error) {
            console.log(error)
        }
    }

    const deleteVideo = (e) => {

        setVideoLinks((videoLinks) => [
            ...videoLinks.filter(link => {
                return link !== e.target.id
            }),
        ]);

    }

    const createVideoCard = (link) => {
        return (
            <div className="mb-1 d-flex flex-column w-100 justify-content-center">
                <div
                    className="video"
                    style={{
                    position: "relative",
                    paddingBottom: "56.25%" /* 16:9 */,
                    // paddingTop: 25,
                    height: 0,
                    }}>
                        <Button id={link} onClick={deleteVideo} style={{zIndex: "2"}} color="danger" size="sm" className="col-1 m-1 position-absolute">x</Button>
                        <iframe
                        style={{
                        position: "absolute",
                        top: 0,
                        left: 0,
                        width: "100%",
                        height: "100%",
                        pointerEvents: "none",
                        borderRadius: "5px",
                        filter: "opacity(.5)",
                        }}
                        src={`https://www.youtube.com/embed/${link}`}
                        frameBorder="0"
                        />
                </div>
            </div>
        )
    }

    return (
        <div className="d-flex flex-column justify-content-center">
            {videoLinks.map(link => {
                const vidCard = createVideoCard(link)
                return <div key={link}>{vidCard}</div>
            })}
            <Card color="dark" className="my-1 py-3 d-flex flex-column w-100 justify-content-center">
                <CardTitle className="align-self-center text-center text-light w-75 mb-1"><h4>Video Link</h4></CardTitle>
                <Input onChange={handleAddVideoLink} placeholder="Paste Youtube Link!" type="url" className="w-75 mb-1 align-self-center"></Input>
                <Button onClick={handleAddVideo} className="align-self-center text-center text-light w-75"><h4>Add Video</h4></Button>
            </Card>
        </div>

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