最近ヒットしているRecoilでカウントダウンアプリを作りましょう!


どうしてまたどうするの?


recoilを適用するには、公式サイトの例に従って操作できます.
recoilをさらに理解するために簡単なカウントダウンアプリを作りたいです!
言語はTypescriptです.
ライブラリはreactを使用しています.
最近Atomic Design Patternに興味がある私もこの小さなアプリに応用してみました.
(成果物は簡単ですが、ディレクトリが複雑な場合があります)
このアプリケーションを使用して、次の目標を達成します.
  • recoil
  • atomとセレクタ
  • を作成してみます.
    |試用
  • useRecoilStatEuseRecoilValuehook
  • selector条件を作成し、条件が適用されるとステータス値を変更

  • アプリケーションは、「+1」ボタンと「-1」ボタン操作を簡単に使用して数値を変更できます.
    この数字はrecoilによってステータスをグローバルに管理します.

    数値が3の場合は、セレクタのsetオプションで0に変更します.
    すべての履歴が画面に表示されます.

    別の構成部品から直接数値を受信して画面に表示し、グローバルなステータス管理を確実にします.

    コードを使ってみよう!


    1.RecoilRoot素子で包む


    まず、Recoilを適用するには、インデックスコンポーネントでreduxを書き込むのと同じ幅を使用します.<RecoilRoot></RecoilRoot>部品で包む<App/>部品
    ただし、この例では、カウントアプリケーションコンポーネントをアプリケーションコンポーネントにカプセル化します.この点に注意してください.App.tsx
    import './App.css';
    
    import AnotherComponent from './component/pages/AnotherComponent';
    import Count from './component/pages/Count';
    import { RecoilRoot } from 'recoil';
    
    function App() {
        return (
            <RecoilRoot>
                <Count />
                <AnotherComponent />
            </RecoilRoot>
        );
    }
    
    export default App;

    2.Atom関数の作成


    正式なcount状態を管理するには、Atom関数を作成して定義する必要があります.countAtom.ts
    import { atom } from 'recoil';
    
    export const countAtom = atom({
        key: 'countState',
        default: 0,
    });
    上記のコードでは、キー値が一意の値であり、デフォルト値を設定する必要があります.

    3.UserRecoil Stateの使用


    上で定義したAtom関数を使用してグローバル・ステータス値をクエリーまたは変更できます.
    これは私個人が後ろに座るメリットだと思います.
    反応器状態を管理する基本代表useStatehookのように.
    グローバル・ステータス値を問合せまたは変更できます.CountViewBox.tsx
    import Number from '../../atoms/Number/Number';
    import React from 'react';
    import { countAtom } from '../../../utils/recoilState';
    import styled from 'styled-components';
    import { useRecoilState } from 'recoil';
    
    const CountViewBox = () => {
        const [count, setCount] = useRecoilState(countAtom);
        return (
            <Container>
                <Number count={count} />
            </Container>
        );
    };
    
    export default CountViewBox;
    使い方はuseStateと似ていて、まったく同じです!
    ここでcount値を受け入れ、Number素子で次のように表示します(「1」の部分が表示されます).

    ステータス値を変更するコードもusStateと同じですControlBox.tsx
    import { useRecoilState } from 'recoil';
    
    import Button from '../../atoms/Button/Button';
    import React from 'react';
    import { countAtom } from '../../../utils/recoilState';
    
    const ControllBox = () => {
        const [count, setCount] = useRecoilState(countAtom);
    		// count 값에서 1만큼 증가
        const onIncrese = () => {
            setCount(() => count + 1);
        };
    
    		//// count 값에서 1만큼 감소
        const onDecrese = () => {
            setCount(() => count - 1);
        };
    
        return (
            <Container>
                <Button text="+1" onClick={onIncrese} />
                <Button text="-1" onClick={onDecrese} />
            </Container>
        );
    };
    ボタンをクリックするたびに、制御関数をバインドし、useRecoilStatesetCountでステータス値を変更します.
    これは、Atom関数のクエリーとステータス値の変更を定義するGaryDuxとContext APIよりも理解しやすい.
    次に,Atom関数の友達選択器を用いて,グローバル状態値を加工して導出する.
    アプリケーションでは、上記セレクタの動作部分は「変更履歴」、3の場合は「0に初期化」です.

    上記の履歴から、デフォルト値と変更値がどのような値なのか、3時に0に初期化されていることがわかります.

    4.セレクタ関数の定義


    セレクタ関数は、既存のAtomで定義されたステータス値を入力し、getオプションでエクスポートしたり、エクスポートを加工したりすることができます.
    また、setオプションでデータを変更することもできます.logHistorySelector.ts
    import {  selector } from 'recoil';
    
    import { countAtom } from './recoilState';
    
    export const logHistorySelector = selector({
        key: 'logHistorySelector',
        get: ({ get }) => {
            let newCount = get(countAtom);
            return `변경된 값은 ${newCount} 입니다.`;
        },
        set: ({ set }, newValue) =>
            set(countAtom, Number(newValue) === 3 ? 0 : Number(newValue)),
    });
    同様に、キー値は一意の値として定義されます.
    getオプションからget関数を読み込み、先に定義したcountAtomというAtom関数をパラメータとして使用します.
    これをnewCount変数として宣言します.
    また、この値を返すときは、変更の履歴を表示する必要があります.
    数値だけではないテキスト値とともに返されます.
    ここでsetオプションもgetオプションと同様ですが、新しい値のnewValueがパラメータに添付されます.newValueはstringであり、ステータス管理値のタイプが数値である場合は、上記のコードに示すように、数値で変換する必要があります.
    setオプションのset関数では、1番目のパラメータはステータス管理のAtom関数で、2番目のパラメータはどのように論理を変更すればいいですか?
    論理を追加しました.新しい値が3の場合、ステータス値は0に変更されます.そうしないと、新しい値に変更されます.
    このようにセレクタを作成したら!!
    既存のatom関数として定義されているuseRecoilStateを作成されたセレクタ関数に変更する必要があります.ControlBox.tsx
    import { useRecoilState, useRecoilValue } from 'recoil';
    
    import Button from '../../atoms/Button/Button';
    import React from 'react';
    import { countAtom } from '../../../utils/recoilState';
    import { logHistorySelector } from '../../../utils/logHistory';
    import styled from 'styled-components';
    
    const ControllBox = () => {
        const count = useRecoilValue(countAtom);
        const [countSelect, setCountSelect] = useRecoilState(logHistorySelector);
        const onIncrese = () => {
            setCountSelect(() => count + 1);
        };
        const onDecrese = () => {
            setCountSelect(() => count - 1);
        };
        return (
            <Container>
                <Button text="+1" onClick={onIncrese} />
                <Button text="-1" onClick={onDecrese} />
            </Container>
        );
    };
    
    export default ControllBox;
    既存のuseRecoilStateでは、countAtomは新しく作成されたセレクタ関数であるパラメータです.
    「logHistorySelector」を追加すると、グローバルステータス値を変更するときにセレクタを使用できます.
    値が3を超えると、0に初期化されます.
    💡 上のコードには「userRecoilState」のほかに「userRecoilValue」があります.
    この二つの違いはその名前にある.
    userRecoilstateは値を表示および変更できます!
    userRecoilValueは値のみクエリーできます!
    次に、セレクタはgetオプションを使用して文字列とカウント値を返します.これは、ログを担当するコンポーネントで表されます.LogBox.tsx
    const LogBox = () => {
        const [count, setCount] = useRecoilState(countAtom);
        const value = useRecoilValue(logHistorySelector);
        const [history, setHistory] = useState<RowItemArg[]>([]);
        const [defaultValue, setDefaultValue] = useState<number>(count);
    
        useEffect(() => {
            setHistory(history => [...history, { text: value }]);
        }, [value]);
    
        return (
            <Container>
                <Box>
                    <LogList data={history} defaultValue={defaultValue} />
                </Box>
            </Container>
        );
    };
    (javascriptユーザーは上のコードのjenericを気にする必要はありません...)
    この構成部品には、変更の履歴のみが表示され、データは操作されません.useRecoilValueクエリのみで返されるデータ値.
    userEffect hookを使用してvalue値に基づいて再レンダリングします.
    value値が変更されると、historyという名前の配列に追加できます.これはLogListコンポーネントに表示される論理です.
    value値は、セレクタが返す値文字列+カウント値であるため、もちろん文字タイプです.
    (ex.「変更された値はn」)
    そのまま下と同じように完成~!

    しかし、ここには好奇心があります.
    本当に本当に全域管理状態なのか・・・・・・・・・・・
    疑心症が発生したApp.tsx内では、上記で作成したCountコンポーネントと同等の層を有するAnotherComponentという名前の構成部品を作成し、ステータス値を取得してクエリーすることを決定します.App.tsx
    import './App.css';
    
    import AnotherComponent from './component/pages/AnotherComponent';
    import Count from './component/pages/Count';
    import { RecoilRoot } from 'recoil';
    
    function App() {
        return (
            <RecoilRoot>
                <Count />
                <AnotherComponent />
            </RecoilRoot>
        );
    }
    
    export default App;
    AnotherComponent.tsx
    import React from 'react';
    import RootWrapper from '../atoms/RootWrapper/RootWrapper';
    import Text from '../atoms/Text/Text';
    import { countAtom } from '../../utils/recoilState';
    import styled from 'styled-components';
    import { useRecoilState } from 'recoil';
    
    const AnotherComponent = () => {
        const [count, setCount] = useRecoilState(countAtom);
        return (
            <RootWrapper>
                <Text text={'recoil 상태를 공유 받고 있음(루트) '} />
                <Container>{count}</Container>
            </RootWrapper>
        );
    };
    
    export default AnotherComponent;
    切り取れない私このようにスクリーンショット...

    とにかく.徐....成功!
    Countエレメントと同じ階層の他のエレメントもcount状態値を受け入れます.
    これにより簡単にカウントアプリケーションが作成され、グローバルな状態管理を行えば複雑なREDUXを使わなくてもよいし、RECOILを使って簡単に状態管理ができる!
    もちろん、アプリケーションの性質によってはReduxも良いかもしれませんが、マージン効果を設定する必要はありません.
    私はグローバル状態を簡単に管理するだけ~~~ならrecoilを使うことをお勧めします!
    githubコードの表示

    Reference


    Recoil公式ホームページ