Top 10 Youtubers 2022 - Charka UI/Vite/Typescript/React  Tutorial - useState, map and display array

Top 10 Youtubers 2022 - Charka UI/Vite/Typescript/React Tutorial - useState, map and display array

This is a great little project to improve your skills. Enjoy.

1. Install Vite + give your project a name (top-ten-youtube) and choose React/typescript

npm create vite@latest

"Vite can speed up development quite a bit"

cd top-ten-youtube
npm install
npm run dev
npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6

2. Open Project in VSC

Delete css files and app.tsx back to the div

function App() {

  return (
    <div className="App">

    </div>
  )
}

export default App

3. Set up Charka Provider and extendTheme inside main.tsx

The extendTheme will give us our background and font colour

import App from './App'
import {ChakraProvider} from '@chakra-ui/react'
import React from 'react'
import ReactDOM from 'react-dom/client'
import { extendTheme } from "@chakra-ui/react"

const theme = extendTheme({
  styles: {
    global: {
      body: {
        bg: '#C53030',
        color: '#2D3748',
      },
    },
  },
})

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ChakraProvider theme={theme}>
    <App />
    </ChakraProvider>
  </React.StrictMode>
)

4. Set up Folders and files

Set up a component folder and two files. One data.tsx and another called youtubers.tsx

image.png

5. Lets setup our data inside data.tsx

export default [
    {
      num: 1,
      id: 1,
      name: 'T-series',
      sub: 22800000,
      image:
        'https://upload.wikimedia.org/wikipedia/commons/7/7d/T-series-logo.svg',
    },
    {
      num: 2,
      id: 2,
      name: 'CocoMelon',
      sub: 146000000,
      image:
        'https://i.scdn.co/image/ab6761610000e5eb3e5fc149e1901d1811096a53',
    },
    {
      num: 3,
      id: 3,
      name: 'Set India',
      sub: 145000000,
      image:
        'https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/SET_India_logo.svg/1765px-SET_India_logo.svg.png',
    },
    {
      num: 4,
      id: 4,
      name: 'PewDiePie',
      sub: 145000000,
      image:
        'https://yt3.ggpht.com/5oUY3tashyxfqsjO5SGhjT4dus8FkN9CsAHwXWISFrdPYii1FudD4ICtLfuCw6-THJsJbgoY=s900-c-k-c0x00ffffff-no-rj',
    },
    {
      num: 5,
      id: 5,
      name: 'MrBeast',
      sub: 109000000,
      image:
        'https://i.pinimg.com/550x/d1/9e/4b/d19e4b9c1f56b1a978c7a66313591ad2.jpg',
    },
    {
      num: 6,
      id: 6,
      name: 'Kids Diana Show',
      sub: 102000000,
      image:
        'https://yt3.ggpht.com/ytc/AMLnZu9RnORdVDP9G2zTBBHBXdHJ6GeWyaepbwtV6H3wmw=s900-c-k-c0x00ffffff-no-rj',
    },
    {
      num: 7,
      id: 7,
      name: 'Like Nastya',
      sub: 102000000,
      image:
        'https://yt3.ggpht.com/_LchAn0SccG_yPxplJ_4_DUucyzqUbxUc-F8YAzOiB8e060zRyX8PrW6vmrJ3ofXJ4AId4iprg=s176-c-k-c0x00ffffff-no-rj-mo',
    },
    {
      num: 8,
      id: 8,
      name: 'WWE',
      sub: 91000000,
      image:
        'https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/WWE_%282014%29_logo.svg/1200px-WWE_%282014%29_logo.svg.png',
    },
    {
      num: 9,
      id: 9,
      name: 'Zee Music Company',
      sub: 89000000,
      image:
        'https://yt3.ggpht.com/EEGERwlaKJd27zSEPQF3d__-tPyppIgFfKvNfBkWa7ssMKBWqQUbuCTLe-kAnTB1r6kJQVxyxwY=s900-c-k-c0x00ffffff-no-rj',
    },
    {
      num: 10,
      id: 10,
      name: 'Vlad and Niki',
      sub: 89000000,
      image:
        'https://yt3.ggpht.com/RlnpUc0SBCmYvseTqUqAfYeyHw0nHcmqQIVS0vMcTKpk3gQAY0ZZY1JpUxxjLPAYROhDYKub=s900-c-k-c0x00ffffff-no-rj',
    },
  ];

6. Set up elements and Image inside app.tsx

The image will be used for the button to dislike.

import { Box, Image, Text } from '@chakra-ui/react'

function App() {
  return (
    <Box>
      <Box as="section">
        <Text>Top 10 Youtubers 2022</Text>
        <Image boxSize='70px' objectFit='cover' onClick={()=> console.log('you clicked me')} src='https://media-cldnry.s-nbcnews.com/image/upload/rockcms/2021-11/211111-youtube-dislike-button-3f091f.jpg' alt='Dislike button' />
      </Box>
    </Box>
  )
}

export default App

7. Set up useState and pass data inside

Our data array will be our initial state. You can also replace the 10 in ''Top 10 YouTubers 2022" with some javascript'

import { Box, Image, Text } from '@chakra-ui/react'
import React, { useState } from 'react'

import data from './Components/data'

function App() {
  const [youTube, setYouTube] = useState(data)
  return (
    <Box>
      <Box as="section">
        <Text>Top {youTube.length} Youtubers 2022</Text>
        <YouTubers youTube={youTube} />
        <Image boxSize='70px' objectFit='cover' onClick={()=> console.log('you clicked me')} src='https://media-cldnry.s-nbcnews.com/image/upload/rockcms/2021-11/211111-youtube-dislike-button-3f091f.jpg' alt='Dislike button' />
      </Box>
    </Box>
  )
}

export default App

8. Set up youtubers.tsx

Pass data into props and map through.

import { Box, Text } from '@chakra-ui/react'

// @ts-ignore
const YouTubers = ({youTube}) => {
  return (
    <>
    {youTube.map((youTuber: any) => {
        const { num, id, name, sub, image } = youTuber;
        return (
          <Box as="article" key={id}>
            <img src={image} alt={name} />
            <Box>
              <Text>{num}. {name}</Text>
              <Text>{sub} Subscribers</Text>
            </Box>
          </Box>
        );
      })}
    </>
  );
};

export default YouTubers;

9. Youtuber.tsx and App.tsx styles

import { Box, Flex, Image, Text } from '@chakra-ui/react'

// @ts-ignore
const YouTubers = ({youTube}) => {
  return (
    <>
    {youTube.map((youTuber: any) => {
        const { num, id, name, sub, image } = youTuber;
        return (
            <Flex alignItems='center' mt="26px" key={id}>
            <Image src={image} alt={name} borderRadius="50%" w="75px" h="75px" mb="2" />
            <Box ml="6">
              <Text fontSize='18px' fontWeight="700">{num}. {name}</Text>
              <Text fontSize='18px' mb="2">{sub} Subscribers</Text>
            </Box>
          </Flex>
        );
      })}
    </>
  );
};

export default YouTubers;
import { Box, Flex, Image, Text } from '@chakra-ui/react'
import React, { useState } from 'react'

import YouTubers from './youtubers'
import data from './data'

function App() {
  const [youTube, setYouTube] = useState(data)
  return (
    <Box as="body" mb="90">
    <Box w='xl' bg='white' ml="500px" pt="5" mt="90" mb="90" rounded='lg' boxShadow='dark-lg'>
      <Flex direction={['column', 'column', 'row']}>
      <Box as="section" mx="6">
        <Text fontSize='3xl' mb="4" ml="4">Top {youTube.length} Youtubers 2022</Text>
        <YouTubers youTube={youTube} />
        <Image borderRadius="15%" w="100px" h="65px" mb="8" mt="8" ml="200" objectFit='cover' onClick={()=> console.log('you clicked me')} src='https://media-cldnry.s-nbcnews.com/image/upload/rockcms/2021-11/211111-youtube-dislike-button-3f091f.jpg' alt='Dislike button' />
      </Box>
      </Flex>
    </Box>
    </Box>
  )
}

export default App

11. Now pass the setYouTube state into the onclick event.

import { Box, Flex, Image, Text } from '@chakra-ui/react'
import React, { useState } from 'react'

import YouTubers from './youtubers'
import data from './data'

function App() {
  const [youTube, setYouTube] = useState(data)
  return (
    <Box as="body" mb="90">
    <Box w='xl' bg='white' ml="500px" pt="5" mt="90" mb="90" rounded='lg' boxShadow='dark-lg'>
      <Flex direction={['column', 'column', 'row']}>
      <Box as="section" mx="6">
        <Text fontSize='3xl' mb="4" ml="4">Top {youTube.length} Youtubers 2022</Text>
        <YouTubers youTube={youTube} />
        <Image borderRadius="15%" w="100px" h="65px" mb="8" mt="8" ml="200" objectFit='cover' onClick={() => setYouTube([])} src='https://media-cldnry.s-nbcnews.com/image/upload/rockcms/2021-11/211111-youtube-dislike-button-3f091f.jpg' alt='Dislike button' />
      </Box>
      </Flex>
    </Box>
    </Box>
  )
}

export default App

12. Lets make it responsive

import { Box, Flex, Image, Text } from '@chakra-ui/react'
import React, { useState } from 'react'

import YouTubers from './youtubers'
import data from './data'

function App() {
  const [youTube, setYouTube] = useState(data)
  return (
    <Flex>
    <Box w='xl' bg='white' ml={['10px', '35px', '500px']} pt="5" mt="90" mb="90" rounded='lg' boxShadow='dark-lg'>
      <Box as="section" mx="6">
        <Text fontSize={['3xl', '3xl', '4xl']} mb="4" ml="4">Top {youTube.length} Youtubers 2022</Text>
        <YouTubers youTube={youTube} />
        <Image borderRadius="15%" w="100px" h="65px" mb="8" mt="8" ml="200" objectFit='cover' onClick={() => setYouTube([])} src='https://media-cldnry.s-nbcnews.com/image/upload/rockcms/2021-11/211111-youtube-dislike-button-3f091f.jpg' alt='Dislike button' />
      </Box>
    </Box>
    </Flex>
  )
}

export default App
import { Box, Flex, Image, Text } from '@chakra-ui/react'

// @ts-ignore
const YouTubers = ({youTube}) => {
  return (
    <>
    {youTube.map((youTuber: any) => {
        const { num, id, name, sub, image } = youTuber;
        return (
            <Flex alignItems='center' mt="26px" key={id}>
            <Image src={image} alt={name} borderRadius="50%" w="75px" h="75px" mb="2" />
            <Box ml="6">
              <Text fontSize={['md', 'md', 'lg']} fontWeight="700">{num}. {name}</Text>
              <Text fontSize={['md', 'md', 'lg']} mb="2">{sub} Subscribers</Text>
            </Box>
          </Flex>
        );
      })}
    </>
  );
};

export default YouTubers;

That's it. Thanks for learning with me. Click follow if you enjoy the tutorial.