Chakra-ui를 사용한 Next.js의 반응형 레이아웃

32448 단어
이번 주 초 저는 next.js에서 Chakra-ui를 사용한 반응형 및 사용자 정의 구성 요소에 대해 게시했습니다.

반응형 레이아웃에 초점을 맞춰 후속작을 작성하고 싶었는데 Chakra-ui GridComponent를 사용하면 쉽게 작업할 수 있습니다.

나는 작은 demo, 작은 프로필과 같은 카드에 일부 친구를 표시하고, 이전에 설명했던 것을 기반으로 만들었습니다.




//pages/index.js

const Home = () => {
  const mainRef = useRef();
  const dimensions = useDimensions(mainRef, true);

  const [size, setSize] = useState('');

  useEffect(() => {
    if (dimensions) {
      let width = dimensions.borderBox.width;
      switch (true) {
        case width < 499:
          setSize('base');
          break;
        case width >= 499 && width < 696:
          setSize('sm');
          break;
        case width >= 696 && width < 945:
          setSize('md');
          break;
        case width >= 945:
          setSize('lg');
          break;
      }
    }
  }, [dimensions]);

  return (
    <>
      <Nav />
      <Box
        w="100vw"
        h="100vh"
        display="flex"
        justifyContent="center"
        ref={mainRef}
        alignItems="flex-start"
        as="main"
      >
        <Layout>
          <MyGrid />
          <Box fontSize={{ base: '20px', sm: '24px' }} mt="30px">
            <Text display="flex" justifyContent="center">
              Width: {dimensions && dimensions.borderBox.width}px
            </Text>
            <Text display="flex" justifyContent="center">
              Custom breakpoint size: {size}
            </Text>
          </Box>
        </Layout>
      </Box>
    </>
  );
};
export default Home;


인덱스 구성 요소는 간단한 사용자 정의 Nav 구성 요소와 Grid 구성 요소를 수용할 레이아웃 컨테이너 구성 요소가 포함된 React Fragment을 반환합니다.


//components/MyGrid.js

import profiles from '../profiles.json';

const MyGrid = () => {
  return (
    <>
      <Grid
        templateColumns={{ base: '1fr', lg: 'repeat(2, 1fr)' }}
        h="100%"
        gap="10px"
        overflow="auto"
        css={{
          '&::-webkit-scrollbar': {
            width: '4px',
          },
          '&::-webkit-scrollbar-track': {
            width: '6px',
          },
          '&::-webkit-scrollbar-thumb': {
            background: 'primary',
            borderRadius: '24px',
          },
        }}
      >
        {profiles.map((profile) => (
          <GridItem
            key={profile.id}
            h="150px"
            bg="primary"
            borderRadius="10"
            color="white"
            display="flex"
            pl={{ base: '10px', sm: '25px', lg: '15px' }}
            alignItems="center"
          >
            <Box display="flex" alignItems="center">
              <ItemAvatar imageSrc={profile.imageSrc} name={profile.name} />
            </Box>
            <Details
              name={profile.name}
              title={profile.title}
              link={profile.linkSrc}
            />
          </GridItem>
        ))}
      </Grid>
    </>
  );
};

export default MyGrid;



Grid 구성 요소는 루트에서 json 파일을 가져오고 해당 데이터를 매핑하고 해당 배열의 각 개체에 대해 Chakra의 Avatar 구성 요소와 자체 사용자 지정 세부 정보 구성 요소가 있는 Chakra의 Grid 항목을 반환합니다.


//components/Details.js

import { Box, Text } from '@chakra-ui/react';
import Link from 'next/link';

const Details = ({ name, title, link }) => {
  return (
    <Box
      display="flex"
      flexDirection="column"
      pl={{ base: '10px', sm: '25px', lg: '15px' }}
      fontSize={{ base: '12px', sm: '14px', md: '16px', lg: '14px' }}
    >
      <Text fontSize="20px"> {name} </Text>
      <Text as="i">{title}</Text>
      <Text color="#03fcfc" as="i">
        <Link href={link}>{link}</Link>
      </Text>
    </Box>
  );
};

export default Details;



이 문서 전체에서 일부 구성 요소 props의 구문{{base: 'someValue', sm: 'someValue', ...}}을 볼 수 있으며 다른 에서 더 자세히 설명하는 것을 볼 수 있지만 요약하면 사용자 정의 중단점을 기반으로 prop이 특정 값이 되도록 지시합니다. 테마에서 정의했습니다.


//styles/ChakraTheme.js

import { extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  colors: {
    primary: '#201D29',
  },
  breakpoints: {
    sm: '499px',
    md: '696px',
    lg: '945px',
  },
});

export default theme;


마지막으로 중단점을 시각화하는 데 도움이 되도록 Chakra의 후크를 활용하여 레이아웃 구성 요소를 래핑하고 상태에 저장하는 상자의 너비를 가져올 수 있으며 구성 요소 크기가 조정될 때마다 useEffect에서 업데이트됩니다.


import { useRef, useState, useEffect } from 'react';
import { Box, Text } from '@chakra-ui/react';
import MyGrid from '../components/MyGrid';
import Layout from '../components/Layout';
import Nav from '../components/Nav';
import { useDimensions } from '@chakra-ui/react';

const Home = () => {
  const mainRef = useRef();
  const dimensions = useDimensions(mainRef, true);

  const [size, setSize] = useState('');

  useEffect(() => {
    if (dimensions) {
      let width = dimensions.borderBox.width;
      switch (true) {
        case width < 499:
          setSize('base');
          break;
        case width >= 499 && width < 696:
          setSize('sm');
          break;
        case width >= 696 && width < 945:
          setSize('md');
          break;
        case width >= 945:
          setSize('lg');
          break;
      }
    }
  }, [dimensions]);

  return (
    <>
      <Nav />
      <Box
        w="100vw"
        h="100vh"
        display="flex"
        justifyContent="center"
        ref={mainRef}
        alignItems="flex-start"
        as="main"
      >
        <Layout>
          <MyGrid />
          <Box fontSize={{ base: '20px', sm: '24px' }} mt="30px">
            <Text display="flex" justifyContent="center">
              Width: {dimensions && dimensions.borderBox.width}px
            </Text>
            <Text display="flex" justifyContent="center">
              Custom breakpoint size: {size}
            </Text>
          </Box>
        </Layout>
      </Box>
    </>
  );
};
export default Home;



초기 로드 시 크기 상태는 빈 문자열const [size, setSize] = useState('')이며 화면에 처음 렌더링된 후 useEffect에서 업데이트됩니다.

Chakra의 차원 개체가 업데이트될 때마다 useEffect의 기능을 트리거합니다. 이 함수는 switch 문을 사용하여 크기 상태를 업데이트할 항목을 결정합니다.

소스 코드here를 볼 수 있습니다.
그리고 날 따라와

좋은 웹페이지 즐겨찾기