Skip to content

Instantly share code, notes, and snippets.

@HectorBlisS
Created August 7, 2022 15:06
Show Gist options
  • Save HectorBlisS/9d5ad2065a6cb2e08bc85329c68dddf0 to your computer and use it in GitHub Desktop.
Save HectorBlisS/9d5ad2065a6cb2e08bc85329c68dddf0 to your computer and use it in GitHub Desktop.
Youtube_Aprende a usar el Fetcher de Remix
import { useLoaderData, useFetcher } from 'remix';
import type { LoaderFunction, ActionFunction } from 'remix';
import { useEffect, useState } from 'react';
const videoIds = [
'57IcpS8x7Ig',
'vjYRTMLoMfs',
'jkNzbkoNFm0',
'43KpZYk8_2E',
'I6eZDxVKj08',
'TDy0pq-PybU',
'b3u9UgjJjqM',
'GMNpqztB4jw',
];
const next = 'https://cdn-icons-png.flaticon.com/512/269/269054.png';
const loading =
'https://thumbs.gfycat.com/CautiousImpassionedBoubou-size_restricted.gif';
//util
function sleep(ms: number): Promise<undefined> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export const loader: LoaderFunction = async () => {
return { videoId: videoIds[0] };
};
export const action: ActionFunction = async ({ request }) => {
const formData = await request.formData();
const current = formData.get('current');
const next = videoIds.filter((video) => video !== current)[
Math.floor(Math.random() * videoIds.length - 1)
];
await sleep(1000);
return { next };
};
export default function Youtube() {
const { videoId } = useLoaderData<{ videoId: string }>();
const fetcher = useFetcher();
const [current, setCurrent] = useState<string>(videoId);
useEffect(() => {
if (fetcher.type === 'done') {
const { next } = fetcher.data;
setCurrent(next);
}
}, [fetcher]);
const handleClick = () => {
fetcher.submit({ current }, { method: 'post' });
};
return (
<section>
<h2
style={{
color: 'blue',
fontSize: '2rem',
textAlign: 'center',
padding: '24px 0',
}}
>
Youtube Catalog
</h2>
<YoutubeVideo
isLoading={fetcher.state !== 'idle'}
id={current}
onClick={handleClick}
/>
</section>
);
}
type YoutubeVideoProps = {
id: string;
onClick: () => void;
isLoading?: boolean;
};
const YoutubeVideo = ({ id, onClick, isLoading }: YoutubeVideoProps) => (
<div>
<iframe
width="560"
height="315"
src={`https://www.youtube.com/embed/${id}`}
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
<div
style={{
display: 'flex',
minHeight: '1rem',
justifyContent: 'center',
gap: '4px',
padding: '1rem 0',
}}
>
<button onClick={onClick} style={{ cursor: 'pointer' }}>
{<img width="200px" alt="like" src={isLoading ? loading : next} />}
</button>
</div>
</div>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment