React UIライブラリ Mantineの使いやすいhooksをまとめてみた

2022.06.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。データアナリティクス事業本部 サービスソリューション部の北川です。

Mantineは、ReactのUIライブラリになります。

基本的な使用方法については、以下のブログで書いています。

MantineはUIコンポーネントの他にも、豊富なhooksを提供しています。今回はその中でも、個人的に使いやすいhooksについて、紹介したいと思います。

use-input-state

use-input-stateは、ネイティブ入力 (onChange ハンドラでイベントを指定) とカスタム入力 (onChange ハンドラで値を指定) の状態を処理します。フックはすべての Mantine およびネイティブインプットで動作します。

use-input-stateは、入力値の状態を管理します。使用するフォームでonChangeに指定します。

import { useInputState } from "@mantine/hooks";
import { TextInput, NumberInput } from "@mantine/core";

const Sample = () => {
  const [stringValue, setStringValue] = useInputState<string>("");
  const [numberValue, setNumberValue] = useInputState<number>(0);

  console.log(stringValue)

  return (
    <div style={{margin: "50px auto", width: "400px"}}>
      <TextInput value={stringValue} onChange={setStringValue} />
      <NumberInput value={numberValue} onChange={setNumberValue} />
    </div>
  );
}

export default Sample;

stringValueの状態を取得できています。

use-focus-within

指定した要素内のフォームに、フォーカスが当たっているかどうかを検出し、真偽値を返します。フォーカスが当たっている場合のみ、スタイルを追加する機能の実装で用います。

import { useFocusWithin } from "@mantine/hooks";
import { TextInput, Button, Box, Text } from "@mantine/core";

const Sample = () => {
  const { ref, focused } = useFocusWithin();
  return (
    <div ref={ref}>
      <Box
        sx={(theme) => ({
          backgroundColor: focused
            ? "lime"
            : "transparent",
          padding: theme.spacing.xl,
        })}
      >
        <Text size="sm">One of elements has focus: {focused.toString()}</Text>
        <TextInput
          label="Focus this input"
          placeholder="Styles will be added to parent"
        />
        <Button mt="md">Button</Button>
      </Box>
    </div>
  );
}

export default Sample;

フォーカスが当たっていない時:false

フォーカスが当たっている時:true

use-element-size

指定した要素の幅と高さを取得できます。

import { Container, Space } from "@mantine/core";
import { useElementSize } from "@mantine/hooks";

const Sample = () => {
  const { ref, width, height } = useElementSize();

  return (
    <Container>
      <Space h="md" />
      <textarea ref={ref} style={{ width: 400, height: 120 }} />
      <div>
        Width: {width}px, height: {height}px
      </div>
    </Container>
  );
}

export default Sample;

use-resize-observer

use-element-sizeと同様、幅と高さを取得し、要素の位置も合わせて取得します。

import { Text, Code, Container, Space } from "@mantine/core";
import { useResizeObserver } from "@mantine/hooks";

const Sample = () => {
  const [ref, rect] = useResizeObserver();

  return (
    <Container>
      <Space h="md" />
      <textarea ref={ref} style={{ width: 400, height: 120 }} />
      <Text align="center">
        Rect: <Code>{JSON.stringify(rect)}</Code>
      </Text>
    </Container>
  );
};

export default Sample;

use-media-query

use-media-queryは、ブラウザ幅に応じて変化する機能を実装できます。引数としてメディアクエリを受け取り、与えられたクエリの条件に対する真偽値を返します。 第二引数には、APIが機能しない場合に対応する、初期値を指定できます。

複雑なスタイリングには適さないですが、簡単な要素の出し入れなどでは、cssを別途記述する必要がなくなります。

import { Badge, Center } from "@mantine/core";
import { useMediaQuery } from "@mantine/hooks";

export const Sample = () => {
  const matches = useMediaQuery("(min-width: 500px)");

  return (
    <Center style={{ width: 400, height: 200 }}>
      <Badge
        suppressHydrationWarning
        color={matches ? "teal" : "red"}
        variant="filled"
      >
        Breakpoint
        {matches ? "matches" : "does not match"}
      </Badge>
    </Center>
  );
};

export default Sample;

まとめ

今回は、Mantineの便利なhooksについて紹介していきました。ここで使用したのは一部で、他にも様々なhooksがあります。Mantineの使用を検討している人は、試してみてください。

ではまた。