ただのメモまとめ 202309

最近フロントエンド結構がっつりやったのでまとめ
がっつり書くの1年に1回程度なので、割と進歩や新ツール郡にびっくりはするけど
その度に勉強するのも結構刺激になって楽しいです。

特定の項目に関してまとめてるわけじゃなく、最近の自分のまとめなので
読みづらいし、参考にもならないかも。

まぁでも書かないよりはいいか。

[React] Classコンポーネントと関数コンポーネント

いつの間にかどっちでも特に問題なくなっている。
(前は関数コンポーネントは制限あったような・・・?)

今風は関数コンポーネントらしい。まぁ確かにピュアな関数で書けば良いし
ReactHookも充実していて不便は特にない。

props,stateも特に違和感ない。(特殊な宣言や呼び出しがない)
stateに関してはむしろ関数コンポーネントのほうが好きかも。

class TestComponent extends React.Component {
    constructor(prosp) {
        super(props)
        this.state = {
            year: 2023
        }
    }

    componentDidMount() {
        // hogehoge
    }
    componentWillUnmount() {
        // fugafuga
    }
}

const TestComponent = (props) {
    const [year, setYear] = React.useSteate(2023)

    React.useEffect(() => {
        // alt componentDidMount

        return () => {
            // fugafuga
        }
    }, [])
}

useEffectの第二引数は依存する値を宣言できて、空にすればマウント時に1回呼び出しされる。
変数に関数を渡すことで、unmount時のコードも宣言できる。

好きなほうでいいので、プロジェクトで相談しましょう

NextJS

これは本当に触りだけなので、わかってる範囲で書きつつ、ナレッジが溜まったら
追記するか別でまとめたいと思ってます。

すごくざっくりいうとReactのサーバーサイドでレンダリングする版。
シングルページではなく、URL単位で静的Webページを生成して返す。
NextJSがサーバー機能を持つ。
Reactと比較してパフォーマンスやSEOの面で有利らしい。

仕事で使ったわけじゃないので調べた情報をまとめただけだけど
単体でいえばReactJSはページ数少ない(構造が)シンプルなWeb
NextJSは複雑でコンテンツが多いものに適しているのかなぁ、という印象。

デプロイ先としてVercelというサービスを使うと非常に簡単らしい。
(無論自分で建てたサーバーにもデプロイ可能)

FramerMotion

https://www.framer.com/motion/

似たようなライブラリはいくつもあるんだけど、機能の豊富さと
開発コミュニティの規模等から最近採用したReact向けアニメーションライブラリ。

個人的には嬉しいことなんですが、去年あたりから自分があまり得意としない
動きに関するコードを触る機会が増えて日々勉強。

これに関しては調べても意外と欲しい日本語の情報は少なかったので
そのうち掘り下げたい

LottieFiles

https://lottiefiles.com/jp/

これ最近はじめて知った。
Webやアプリ向けに軽量アニメーションを作成して、SVGアニメーションにしてくれるサービス。

僕はデザイナさんが作ったデータを呼び出しただけなんで詳しくはよくわかんないけど
サービス自体無料でも使えて便利そうだった。

他のライブラリがどうなってるか見てないけど、React用の公式ライブラリも存在するし
例えばイベントにフックしてアニメーションを再生する、みたいなのも簡単。

最近vs codeのvimバグった

これが全て
https://dev.classmethod.jp/articles/fixing-weird-behavior-in-vscodevim-v1-26-0-on-vs-code/

修正されるまではダウングレードしましょう。

code --install-extension vscodevim.vim@1.25.2

MacのVisual Studioずーーーーっとこの状態でコメントだけvscodeで書いてたのに
vscodeまで最近バグってビビりました。

SCSS

何年前の話しとんじゃ、だけど。もうこれが標準になってほしい。
他のプロジェクトがどうなってるか、そこまで掘ってないけど下記のような書き方をしたいなって思いました。
(名前は適当)

  • app.scss
    • リセットスタイルとか、bodyとか*とか、font-styleとか。一回だけreadされるような感じ
  • common.scss
    • 色とかサイズの変数とか、メディアクエリとか。includeして使うやつ
  • thema.scss
    • common.scssの値を使って汎用的なHTMLElementに当てるとりあえずなやつ。
    • buttonとかpとかh1-h5とかinput[type=text]とかの初期の見た目みたいな
    • buttonもinfo,error,warningとかあってもいいかも?
    • 使いまわしたいやつ、一回だけreadされる
  • [ComponentName].scss
    • コンポーネント単位で使われるやつ。(Componentの数だけ作られる)
    • 本当はこれなくてもthema.scssだけでなんかそれっぽくなったら最高だけど。

スクロールバーなくしたいマン

.class_name {
    overflow: scroll;
    /* IE, Edge 対応 */
    -ms-overflow-style: none;
    /* Firefox 対応 */
    scrollbar-width: none;
}
/* Chrome, Safari 対応 */
.class_name::-webkit-scrollbar {
    display:none;
}

アンチエイリアスできるだけ頑張る

* {
    font-weight: 100;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

ピンチイン・アウト禁止!

body {
    // disable pinch zoom
    touch-action: pan-x pan-y;
}

右クリック禁止(サンプルは画像右クリック禁止)

var guard_selector = document.querySelectorAll<HTMLElement>('img');
for(var n = 0; n < guard_selector.length; n++){
    guard_selector[n].addEventListener("contextmenu", function(e){
      e.preventDefault();
    }, false);
  }

ReactでWindowEventとかフックするやつ

これを使いたいComponentでimportしてuseEffectみたいにすればOK

export const useWindowEvent = <K extends keyof WindowEventMap>(
  type: K,
  listener: (this: Window, ev: WindowEventMap[K]) => any,
  deps: DependencyList,
  options?: boolean | AddEventListenerOptions
) => useEffect(() => {
    if (window) {
      window.addEventListener(type, listener, options);
      return () => {
        window.removeEventListener(type, listener, options);
      };
    }
}, deps);

Reactでscroll検知

loadshのthrottle使うと第二引数に渡したミリ秒で間引いてくれる
(スクロールとかグリグリされたらイベント一気にむっちゃ発火するため)

    // スクロールするHTMLエレメントにわたす
    const scrollableRef = useRef<HTMLDivElement | null>(null);

    useEffect(()=> {
        const handleScroll = throttle((event) => {
            if (!scrollableRef.current) return;
            //hogehoe
        }, 300);

        const scrollable = scrollableRef.current;
        if (scrollable) {
            scrollable.addEventListener('scroll', handleScroll);
        }

        // 当コンポーネントがunmountされるときにremoveしましょう
        return () => {
            if (scrollable) {
                scrollable.removeEventListener('scroll', handleScrollEx);
            }
        };
    }, [])
上部へスクロール