20201124のReactに関する記事は18件です。

Recoil公式ドキュメント 翻訳㉟ APIリファレンス-Core-実用(Utils)-noWait()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


noWait(state)

指定されたatomまたはselectorの現在のstateのLoadableを返すselectorヘルパー。

function noWait<T>(state: RecoilValue<T>): RecoilValueReadOnly<Loadable<T>>

​このヘルパーを使用すると、エラーが発生した場合や依存関係が保留中の場合に、スローすることなく非同期の可能性のある依存関係の現在のstateを取得できます。​useRecoilValueLoadable()と似ていますが、hookではなくselectorである点が異なります。​noWait()はselectorを返すので、今度はhookだけでなく他のRecoil selectorでも使用できます。

サンプルコード

const myQuery = selector({
  key: 'MyQuery',
  get: ({get}) => {
    const loadable = get(noWait(dbQuerySelector));

    return {
      hasValue: {data: loadable.contents},
      hasError: {error: loadable.contents},
      loading: {data: 'placeholder while loading'},
    }[loadable.state];
  }
})

参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉞ APIリファレンス-Core-実用(Utils)-waitForNone()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


waitForNone(dependencies)

要求された依存関係の現在のstateに対するLoadableのセットを返す並行性ヘルパー。​

依存関係は、タプル配列またはオブジェクト内の名前付き依存関係として指定できます。


function waitForNone(dependencies: Array<RecoilValue<>>):
  RecoilValueReadOnly<UnwrappedArrayOfLoadables>
function waitForNone(dependencies: {[string]: RecoilValue<>}):
  RecoilValueReadOnly<UnwrappedObjectOfLoadables>

waitForNone()waitForAll()と似ていますが、値を直接返すのではなく、すぐに戻り、各依存関係に対してLoadableを返す点が異なります。​noWait()と似ていますが、一度に複数の依存関係を要求できる点が異なります。

​このヘルパーは、部分的なデータを操作する場合や、別のデータが使用可能になったときにUIを段階的に更新する場合に便利です。

Incremental Loading の例

​次の使用例は、複数のレイヤを持つグラフを表示します。​各画層には、コストがかかる可能性のあるデータクエリーがあります。​ペンディング(保留)中の各レイヤーの編集ボックスを使用してグラフを即座にレンダリングし、そのレイヤーのデータが入力されるたびにグラフを更新して新しい各レイヤーを追加します。​クエリーでエラーが発生した画層がある場合、その画層だけにエラーメッセージが表示され、残りの画層は引き続きレンダリングされます。

function MyChart({layerQueries}: {layerQueries: Array<RecoilValue<Layer>>}) {
  const layerLoadables = useRecoilValue(waitForNone(layerQueries));

  return (
    <Chart>
      {layerLoadables.map((layerLoadable, i) => {
        switch (layerLoadable.state) {
          case 'hasValue':
            return <Layer key={i} data={layerLoadable.contents} />;
          case 'hasError':
            return <LayerErrorBadge key={i} error={layerLoadable.contents} />;
          case 'loading':
            return <LayerWithSpinner key={i} />;
        }
      })}
    </Chart>
  );
}

参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉝ APIリファレンス-Core-実用(Utils)-waitForAny()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


waitForAny(dependencies)

要求された依存関係の現在のstateに対するLoadableのセットを返す並行性ヘルパー。
​少なくとも1つの依存関係が使用可能になるまで待機します。

​依存関係は、タプル配列またはオブジェクト内の名前付き依存関係として指定できます。


function waitForAny(dependencies: Array<RecoilValue<>>):
  RecoilValueReadOnly<UnwrappedArrayOfLoadables>
function waitForAny(dependencies: {[string]: RecoilValue<>}):
  RecoilValueReadOnly<UnwrappedObjectOfLoadables>

​waitForAny()waitForNone()に似ていますが、少なくともひとつの依存性がすぐに値を返すのではなく、利用可能になるまで待つという点が異なります。


参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉜ APIリファレンス-Core-実用(Utils)-waitForAll()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


waitForAll(dependencies)

複数の非同期依存関係を同時に評価することを可能にする並行性ヘルパー。

​依存関係は、タプル配列またはオブジェクト内の名前付き依存関係として指定できます。


function waitForAll(dependencies: Array<RecoilValue<>>):
  RecoilValueReadOnly<UnwrappedArray>
function waitForAll(dependencies: {[string]: RecoilValue<>}):
  RecoilValueReadOnly<UnwrappedObject>

​並行性ヘルパーはselectorとして提供されるため、ReactコンポーネントのRecoil hookによって、Recoil selectorの依存関係として、またはRecoil stateが使用されるすべての場所で使用できます。

サンプルコード

function FriendsInfo() {
  const [friendA, friendB] = useRecoilValue(
    waitForAll([friendAState, friendBState])
  );
  return (
    <div>
      Friend A Name: {friendA.name}
      Friend B Name: {friendB.name}
    </div>
  );
}
const friendsInfoQuery = selector({
  key: 'FriendsInfoQuery',
  get: ({get}) => {
    const {friendList} = get(currentUserInfoQuery);
    const friends = get(waitForAll(
      friendList.map(friendID => userInfoQuery(friendID))
    ));
    return friends;
  },
});
const customerInfoQuery = selectorFamily({
  key: 'CustomerInfoQuery',
  get: id => ({get}) => {
    const {info, invoices, payments} = get(waitForAll({
      info: customerInfoQuery(id),
      invoices: invoicesQuery(id),
      payments: paymentsQuery(id),
    }));

    return {
      name: info.name,
      transactions: [
        ...invoices,
        ...payments,
      ],
    };
  },
});

参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉛ APIリファレンス-Core-実用(Utils)-errorSelector()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


errorSelector(message)

​提供されたエラーを常にスローするselector

function errorSelector(message: string): RecoilValueReadOnly

サンプルコード

const myAtom = atom({
  key: 'My Atom',
  default: errorSelector('Attempt to use Atom before initialization'),
});

参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉚ APIリファレンス-Core-実用(Utils)-constSelector()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


constSelector(constant)

​常に一定の値を提供するselector.

function constSelector<T: Parameter>(constant: T): RecoilValueReadOnly<T>

constSelectorは、異なるselector実装によって提供されるRecoilValue<T>RecoilValueReadOnly<T>などのタイプを使用するインタフェースがある場合に便利です。

​これらのselectorは、参照値の等価性に基づいて記憶します。​したがって、constSelector()を同じ値で複数回呼び出すことができ、同じselectorが提供されます。​このため、定数として使用される値は、Recoil serializationを使用してシリアライズできる型に制限されます。​制限については、selectorFamilyのドキュメントを参照してください。

サンプルコード

type MyInterface = {
  queryForStuff: RecoilValue<Thing>,
  ...
};

const myInterfaceInstance1: MyInterface = {
  queryForStuff: selectorThatDoesQuery,
};

const myInterfaceInstance2: MyInterface = {
  queryForStuff: constSelector(thing),
};

参考サイト

公式ドキュメント
IT用語辞典 e-Words シリアライズ
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉙ APIリファレンス-Core-実用(Utils)-selectorFamily()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


Coming soon...


参考サイト

公式ドキュメント
みらい翻訳


全目次

****

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rcoilつかってみたったった

はじめに

ReactとReduxを勉強し始めて3ヶ月ほどの私ですが

Redux以外の状態管理ライブラリーを使ってみたい!!

とのことで今回Recoilを学習してみました

Recoilとは

Recoil.png

faceBookさんが作ったReactの状態管理ライブラリー。その名の通り真ん中にコイルみたいなのあるね

さっそく使ってみよう

Atoms

index.js
import { atom } from "recoil";

export const textState = atom({
  key: "textState",
  default: "",
});

atomsは一意とkeyとdefaultのStateを設定する

その名の通りdefaultはReactのHooksのuseStateの初期値みたいな感じです

このatomのStateにdataが入ってきます

App.jsx
import { RecoilRoot } from "recoil";
import Router from "./Router";

const App = () => {
  return (
    <RecoilRoot>
      <Router /> 
    </RecoilRoot>
  );
};

atomsのStateはRecoilRootでラップしたコンポーネントは参照できます

selector

selector.js
import { selector } from "recoil";
import { textState } from "../index";

export const textCountState = selector({
  key: "textCountState",
  get: ({ get }) => {
    const text = get(textState);

    return text.length;
  },
});

atomsのstate(textState)を受け取って別の処理をした値を返すことができる

selector.js
import { selector } from "recoil";
import { userNamesList } from "../index";
import api from "../../../services/api";

export const userToFollowerMap = selector({
  key: "userToFollowerMap",
  get: async ({ get }) => {
    const _userNamesList = get(userNamesList);

    const responses = await Promise.all(
      _userNamesList.map((userName) => api.get(`/users/${userName}`))
    );
    const followerMap = {};
    responses.forEach((response) => {
      const { data: user } = response;

      followerMap[user.login] = user.followers;
    });
    return followerMap;
  },
});

こんな感じに非同期処理のQueryとしてStateを受けとり、取得した値を返すこともできる

ではComponentごとにatomsやselectorのStateを追加したり参照する方法

useRecoilState

Textinpu.jsx
import React from "react";
import { useRecoilState } from "recoil";
import { textState } from "../atoms/text/index";

const TextInput = () => {
  const [text, setText] = useRecoilState(textState);

  const onChange = (e) => {
    setText(e.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo:{text}
    </div>
  );
};

ReactのHoosのグローバルState版みたいな感じに使える

textで値を参照できて,setTextでatomsに値を追加できるuseRecoilStateにはatomsのStateを渡す

useSetRecoilState

Textinput.jsx
  const setText = useSetRecoilState(textState);

useRecoilStateのatomsに追加できるだけ版setTextで追加できます。

参照もするのであればuseRecoilStateをつかえばいいかな

useRecoilValue

textLengthCount.jsx
import { useRecoilValue } from "recoil";
import { textCountState } from "../atoms/text/selectors/charCount";

const  textLengthCount = () => {
  const count = useRecoilValue(textCountState);

  return <div>text length Count: {count}</div>;
};

逆に参照だけできる版

atomsやSelectorの値をComponenごとで参照できる

まとめ

Reduxより簡単にかける反面atoms内のオブジェクトに再代入しようとしたらReadOnlyですっておこられた

もうちょっと使ってみてReduxとRecoil両方つかって挙あげれるようになりたい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil使ってみたったった

はじめに

ReactとReduxを勉強し始めて3ヶ月ほどの私ですが

Redux以外の状態管理ライブラリーを使ってみたい!!

とのことで今回Recoilを学習してみました

Recoilとは

Recoil.png

Reactの状態管理ライブラリー。その名の通り真ん中にコイルみたいなのあるね

最近Reduxを抜いて1位になったらしい(世界基準)

さっそく使ってみよう

Atoms

index.js
import { atom } from "recoil";

export const textState = atom({
  key: "textState",
  default: "",
});

atomsは一意とkeyとdefaultのStateを設定する

その名の通りdefaultはReactのHooksのuseStateので初期値みたいな感じです

このatomのStateにdataが入ってきます

App.jsx
import { RecoilRoot } from "recoil";
import Router from "./Router";

const App = () => {
  return (
    <RecoilRoot>
      <Router /> 
    </RecoilRoot>
  );
};

atomsのStateはRecoilRootでラップしたコンポーネントは参照できます

selector

selector.js
import { selector } from "recoil";
import { textState } from "../index";

export const textCountState = selector({
  key: "textCountState",
  get: ({ get }) => {
    const text = get(textState);

    return text.length;
  },
});

atomsのstate(textState)を受け取って別の処理をした値を返すことができる

selector.js
import { selector } from "recoil";
import { userNamesList } from "../index";
import api from "../../../services/api";

//textStateを取得
export const userToFollowerMap = selector({
  key: "userToFollowerMap",
  get: async ({ get }) => {
    const _userNamesList = get(userNamesList);

    const responses = await Promise.all(
      _userNamesList.map((userName) => api.get(`/users/${userName}`))
    );
    const followerMap = {};
    responses.forEach((response) => {
      const { data: user } = response;

      followerMap[user.login] = user.followers;
    });
    return followerMap;
  },
});

こんな感じに非同期処理のQueryとしてStateを受けとり、取得した値を返すこともできる

ではComponentごとにatomsやselectorのStateを追加したり参照する方法

useRecoilState

Textinpu.jsx
import React from "react";
import { useRecoilState } from "recoil";
import { textState } from "../atoms/text/index";

const TextInput = () => {
  const [text, setText] = useRecoilState(textState);

  const onChange = (e) => {
    setText(e.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo:{text}
    </div>
  );
};

ReactのHoosのグローバルState版みたいな感じに使える

textで値を参照できて,setTextでatomsに値を追加できるuseRecoilStateにはatomsのStateを渡す

useSetRecoilState

Textinput.jsx
  const setText = useSetRecoilState(textState);

useRecoilStateのatomsに追加できるだけ版setTextで追加できます。

参照もするのであればuseRecoilStateをつかえばいいかな

useRecoilValue

textLengthCount.jsx
import { useRecoilValue } from "recoil";
import { textCountState } from "../atoms/text/selectors/charCount";

const  textLengthCount = () => {
  const count = useRecoilValue(textCountState);

  return <div>text length Count: {count}</div>;
};

逆に参照だけできる版

atomsやSelectorの値をComponenごとで参照できる

まとめ

Reduxより簡単にかける反面atoms内のオブジェクトに再代入しようとしたらReadOnlyですっておこられた

もうちょっと使ってみてReduxとRecoil両方つかって挙げれるようになりたい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reduxに疲れたそこの奥さんRecoilも使ってみませんか

はじめに

ReactとReduxを勉強し始めて3ヶ月ほどの私ですが

Redux以外の状態管理ライブラリーを使ってみたい!!

とのことで今回Recoilを学習してみました

Recoilとは

Recoil.png

faceBookさんが作ったReactの状態管理ライブラリー。その名の通り真ん中にコイルみたいなのあるね

さっそく使ってみよう

Atoms

index.js
import { atom } from "recoil";

export const textState = atom({
  key: "textState",
  default: "",
});

atomsは一意とkeyとdefaultのStateを設定する

その名の通りdefaultはReactのHooksのuseStateの初期値みたいな感じです

このatomのStateにdataが入ってきます

App.jsx
import { RecoilRoot } from "recoil";
import Router from "./Router";

const App = () => {
  return (
    <RecoilRoot>
      <Router /> 
    </RecoilRoot>
  );
};

atomsのStateはRecoilRootでラップしたコンポーネントは参照できます

selector

selector.js
import { selector } from "recoil";
import { textState } from "../index";

export const textCountState = selector({
  key: "textCountState",
  get: ({ get }) => {
    const text = get(textState);

    return text.length;
  },
});

atomsのstate(textState)を受け取って別の処理をした値を返すことができる

selector.js
import { selector } from "recoil";
import { userNamesList } from "../index";
import api from "../../../services/api";

export const userToFollowerMap = selector({
  key: "userToFollowerMap",
  get: async ({ get }) => {
    const _userNamesList = get(userNamesList);

    const responses = await Promise.all(
      _userNamesList.map((userName) => api.get(`/users/${userName}`))
    );
    const followerMap = {};
    responses.forEach((response) => {
      const { data: user } = response;

      followerMap[user.login] = user.followers;
    });
    return followerMap;
  },
});

こんな感じに非同期処理のQueryとしてStateを受けとり、取得した値を返すこともできる

ではComponentごとにatomsやselectorのStateを追加したり参照する方法

useRecoilState

Textinpu.jsx
import React from "react";
import { useRecoilState } from "recoil";
import { textState } from "../atoms/text/index";

const TextInput = () => {
  const [text, setText] = useRecoilState(textState);

  const onChange = (e) => {
    setText(e.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo:{text}
    </div>
  );
};

ReactのHoosのグローバルState版みたいな感じに使える

textで値を参照できて,setTextでatomsに値を追加できるuseRecoilStateにはatomsのStateを渡す

useSetRecoilState

Textinput.jsx
  const setText = useSetRecoilState(textState);

useRecoilStateのatomsに追加できるだけ版setTextで追加できます。

参照もするのであればuseRecoilStateをつかえばいいかな

useRecoilValue

textLengthCount.jsx
import { useRecoilValue } from "recoil";
import { textCountState } from "../atoms/text/selectors/charCount";

const  textLengthCount = () => {
  const count = useRecoilValue(textCountState);

  return <div>text length Count: {count}</div>;
};

逆に参照だけできる版

atomsやSelectorの値をComponenごとで参照できる

まとめ

Reduxより簡単にかける反面atoms内のオブジェクトに再代入しようとしたらReadOnlyですっておこられた

もうちょっと使ってみてReduxとRecoil両方つかって挙あげれるようになりたい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉘ APIリファレンス-Core-実用(Utils)-atomFamily()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


Coming soon...


参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉒ APIリファレンス-Core-雑録(Misc)-useRecoilBridgeAcrossReactRoots()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


Coming soon...


参考サイト

公式ドキュメント
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Recoil公式ドキュメント 翻訳㉗ APIリファレンス-Core-雑録(Misc)-useRecoilBridgeAcrossReactRoots()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

公式ドキュメント

目次

全目次は一番下にあります


useRecoilBridgeAcrossReactRoots()

このhookは、ネストされたReact rootとレンダラーでRecoil stateをブリッジするのに役立ちます。

function useRecoilBridgeAcrossReactRoots_UNSTABLE():
  React.AbstractComponent<{children: React.Node}>;

ネストされたReact rootがReactDOM.render()で作成された場合、またはネストされたカスタムレンダラーが使用された場合、Reactはコンテキストのstateを子ルートに伝播しません。​このhookは、"bridge"とReact rootがネストされたRecoil stateを共有する場合に便利です。​hookはReactコンポーネントを返します。このコンポーネントは、ネストされたReact rootの代わりに使用して、同じ一貫性のあるRecoil store stateを共有できます。​Reactのルート間でstateを共有する場合と同様に、すべてのケースで変更が完全に同期されるとは限りません。

サンプルコード

function Bridge() {
  const RecoilBridge = useRecoilBridgeAcrossReactRoots_UNSTABLE();

  return (
    <CustomRenderer>
      <RecoilBridge>
        ...
      </RecoilBridge>
    </CustomRenderer>
  );
}

function MyApp() {
  return (
    <RecoilRoot>
      ...
      <Bridge />
    </RecoilRoot>
  );
}

参考サイト

公式ドキュメント
IT用語辞典 e-Words レンダラー
IT用語辞典 e-Words ブリッジ
みらい翻訳


全目次

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reactのkeyを使って、意図的な再レンダーを走らせる

「え?keyって無駄なレンダリングが走らない様にするためのものでしょ?」

その通りなのですが、今回は逆に利用する方法を紹介します。

仕組み

  • keyは異なるレンダー間でどの子要素が変化しない可能性があるのかについてヒントを出すことができるものである 公式
  • 逆に、keyが違う(変わった)のであれば、それは別物として扱われる

利用例1、defaultValueの変更

defaultValueは、非制御コンポーネントの場合に用いる初回のみ設定可能な入力値です。
初回のみなので後から変更することができないのですが、これを変更したいケースがあります。例えばdefaultValueにAPIから取得した値を入れたい場合、具体的には編集フォームで編集元データをfetchしてくるけれど、その前からスケルトンとして入力フォームは見せておきたい場合です。

まずは動かないコードです。
前述の通り、defaultValueは初回のみしか設定できないので、最初に渡された "empty..." のまま変化しません。


See the Pen
no_key_defaultValue
by ぷーたんは社会人リハビリ中 (@putan)
on CodePen.

そこでfetchしたデータを含めた値をkeyに指定します。
これによりInpurFromは別物になったと判断して再レンダーされ、defaultValueも再度読み込ませることができるのです。

- <InputForm defaultValue={val} />
+ <InputForm defaultValue={val} key={`input_${val}`} />

See the Pen with_key_defaultValue by ぷーたんは社会人リハビリ中 (@putan) on CodePen.

利用例2、汎用的なリストの切替

非制御だけでなく、制御コンポーネントでも利用ケースが考えられます。
セレクトボックスやラジオボタン、チェックボックスなどのリスト系フォームでリストを切り替えたいケースです。
サンプルとして二段に分かれたラジオボタンを用意しました。

まずは動かないパターンです。
1段階目のメインメニューをパンに変更してサブメニューが切り替わっても、サブメニューのstateにはごはんの時の値が保持されているためサブメニューが未選択状態になってしまいます。


See the Pen
no_key_radio
by ぷーたんは社会人リハビリ中 (@putan)
on CodePen.

そこでサブメニューのRadioGroupにkeyにメインメニューのRadioGroupの値をkeyとして渡します。
これにより、メインメニューの変更するとサブメニューのRadioGroupも別物として判断され、local stateも初期化されます。

  <RadioGroup
+   key={mainMenu}
    name="subMenu"

See the Pen with_key_radio by ぷーたんは社会人リハビリ中 (@putan) on CodePen.

まとめ

  • keyを利用してdefaultValueやsetStateの初期値などをリセットする方法を紹介
  • うまく使うことでuseEffectなどを用いた複雑な処理を書かなくても意図した制御が可能になる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Webアプリ未経験者がReactチュートリアルに手を出す

HelloWorldは出来たけど、次はどこに行こうか・・・と悩んだが、幸いにして公式のチュートリアルが日本語化されていたので、ここを進めることにした。

チュートリアル:Reactの導入
https://ja.reactjs.org/tutorial/tutorial.html

開発エディタ(Visual Studio Code)

どうもLinux=viというのが染み付いてしまっているのだが、GUIの開発環境をまともに使ったことが無いことだし、この機に何かしら触ってみることにした。

自分のイメージはEclipseのガリレオぐらいで止まっているのだが、既にEclipseは過去の産物のようで・・・ということで、マイクロソフト社のVisual Studio Code(VScode)を入れる。

Microsoft Visual Code Studio
https://code.visualstudio.com/

  1. 開発環境はLinux Mintなので「.deb」をダウンロード(執筆時点:v1.51.1)
  2. ダウンロードしたファイルを右クリック→[GDebiパッケージインストーラーで開く]→開いたダイアログで「パッケージのインストール」を選ぶ
  3. インストールが終わったら、mマーク→プログラミング→Visual Studio Codeを選ぶとVScodeが起動する
  4. しかし、メニューが全て英語なので、以下の手順を経て日本語表示に変更する
    1. メニューバーの[View]
    2. [Command Pallete]
    3. [Configure Display Language]
    4. [Install Language Packs]
    5. 「日本語」を選択して「インストール」
    6. VScodeを再起動
  5. 試しにメニューバーの[ファイル]→[フォルダーを開く]→helloworldを作ったときのフォルダを選んで[OK]を押すと

qiita_20201120_1.png

お、なんか作ってる雰囲気が出てきた。

Reactチュートリアル

開発エディターの準備が出来たので、改めてチュートリアルを進める。

チュートリアルの準備

ターミナルとVSCodeを使いながら、オプション2の手順を進める。

  • ターミナルからチュートリアル用の新しいプロジェクトを、create-react-appを使って作成する。
$ npx create-react-app tutorial
  :
 (しばらく時間がかかる)
 :
Happy hacking!
$
  • VScodeで「tutorial」フォルダーを開き、tutorial/src配下のファイルを全て削除する
    qiita_20201120_2.png

  • メニューバーの[ファイル]→[新規ファイル]をクリックすると、右ペインに空のファイル(Untitled-1タブ)が表示される。
    qiita_20201120_3.png

  • チュートリアルで指示されているサイト(ウェブエディター)の「CSS」を全コピーし、VScodeの右ペインに貼り付ける
    qiita_20201120_4.png

  • メニューバーの[ファイル]→[名前を付けて保存]→src配下を指定し、index.cssと入力して[保存]を押す。正しければツリーのsrcの下にindex.cssが表示される。
    qiita_20201120_5.png

  • 同様の手順で「js」の内容をコピー&ペーストした上で、先頭行にチュートリアルページで示されている3行を加え、index.jsという名前で保存する。

qiita_20201120_6.png

  • ターミナルで「npm start」を実行し、ブラウザからlocalhost:3000に接続する。三目並べの画面が表示されればOK。 qiita_20201120_7.png

ということで準備完了!

チュートリアルを進める

HPの記載に沿って進めるものなので、詰まること無く進められた(ちょくちょくコードを書き換えるので、書き換え漏れによるエラーは何度もあったが)。

ターミナル

当初、VSCodeとターミナルをそれぞれ開きながらやっていたが、ふと見るとVSCodeにターミナルなんてものが・・・。

[ターミナル]を選ぶと開いているフォルダー配下で始まるので、ここで「npm start」を実行すればすぐに動作確認ができる。また、コードを保存すると自動的に反映されるが、コードにエラーがあった場合にこのターミナルにエラーメッセージが表示されるのが便利だった。

qiita_20201124_1.png

てか、今時当たり前なのだろうが。

なお「sudo npm start」としないとエラーが出まくって開発サイトが起動しなかったが、そういうものなのだろうか。

React Developer Tools

React用の開発ツールはChrome(Chromium)やFireFoxの拡張機能として提供されている。

チュートリアルのサイトを開いた状態で、
1. ブラウザの[設定]
2. [その他のツール]
3. [デベロッパーツール]
4. タブの(Reactアイコンのある)[Components]

を選ぶと、画面に対するコンポーネント構成や各コンポーネントの状態を確認することができた。
qiita_20201134_2.png

このチュートリアルでは学習内容の都合上、情報の格納域でちょくちょく変わるので、どのコンポーネントで保持されていて、どう書き換わっているのかが見ることが出来、コードと動作の理解の一助になった。

参考:https://qiita.com/s_harada/items/3a06567c1e7d8ec8b178

応用問題

チュートリアルの最後には以下の「改良のアイデア」がリストアップされている。

  1. 履歴内のそれぞれの着手の位置を (col, row) というフォーマットで表示する
  2. 着手履歴のリスト中で現在選択されているアイテムをボールドにする
  3. Board でマス目を並べる部分を、ハードコーディングではなく 2 つのループを使用するように書き換える
  4. 着手履歴のリストを昇順・降順いずれでも並べかえられるよう、トグルボタンを追加する
  5. どちらかが勝利した際に、勝利につながった 3 つのマス目をハイライトする
  6. どちらも勝利しなかった場合、結果が引き分けになったというメッセージを表示する

見様見真似で1に着手してみたが、今の所どうにもうまくいかない・・・なので、次はこちらのガイドを読み進めてから、再チャレンジしようと思う。

雑感

  • Webアプリ未経験者からするとReactとその他との差異は感じ取れなかったが、チュートリアルが言う要素、コンポーネント、Props、Stateについては何となくわかった気はする
  • 画面系はすぐに動きが見えるので楽しく、うまく動かないとストレスがすぐに溜まってしまう・・・

補足:Reactのバージョン確認

インストールされているReactのバージョンを調べたいときの手順は以下の通り。

  1. ターミナルでプロジェクトの配下に移動(cdコマンド)
  2. 「npm list --depth=0」を実行すると、Reactを含めたmoduleのバージョンが表示される
~/work/web/helloworld$ npm list --depth=0
helloworld@0.1.0 /home/xxx/work/web/helloworld
├── @testing-library/jest-dom@5.11.6
├── @testing-library/react@11.2.0
├── @testing-library/user-event@12.2.2
├── react@17.0.1
├── react-dom@17.0.1
├── react-scripts@4.0.0
└── web-vitals@0.2.4

この時点での最新(17.0.1)になっていた。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsとReact.js

私について

・文系
・プログラミング経験1年
・サマーハッカソン優勝
・大手IT企業を目指して就活中

なぜ記事を書くのか?

今まで楽しくてコードはたくさん書いてきたが、ほとんどが動いたら良いやと仕組みやシステムについてあまり考えてこなかった。一流のエンジニアを目指す上で、なんとなくではなく、根拠をもって技術選定ができたりエラーを解決をできるように記事を書いていく。

技術選定の仕方

・自分のやりたい事が実現しやすい
・情報量が多い

プログラミングはあくまでも手段でしかなく、プロダクトの価値を最大化させることこそが目的である。またプログラミング言語は、基礎文法は少し変わるぐらいで大した差はない。言語に縛られるよりも、自分が言語に合わせて勉強していくほうが、プロダクトの価値も開発効率も上がる。

Vue.jsとReact.jsどっちが簡単?

結論から言うと、vue.jsのほうが圧倒的に簡単です。

Vue.jsのメリット

①SFC(Single File Component)
HTML/JavaScript/CSSが区別して管理でき、Web制作上がりの僕のような人にはとっつきやすい。

②Vue CLIが便利
TypeSclipt、ESLint などの plugin の使用などをコマンドラインの指示に従って簡単に導入できる。

③HMR(Hot Module Replacement)
ブラウザ画面の再描画(リロード)すること無しにコードの変更をブラウザに適用してくれるので、手間が減って開発が楽になる。

上記3つの点が、僕のような初学者でも簡単に感覚的にコードを書くことができ、かつ多くのことが容易に実現できる。

では、React.jsのメリットって?

①主にクラスベースで実装するため、大規模開発に適している。

②typescriptとの組み合わせが良い。

最後に

手軽さという面でVue.jsを選定してきましたが、これからtypescriptがもっと流行すること、会社での大規模開発に携わるであろうことから、Reactの開発もしていこうと考える。
最後まで読んでいただき、ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React hooksを基礎から理解する (useRef編)

React hooksとは

React 16.8 で追加された新機能です。
クラスを書かなくても、 stateなどのReactの機能を、関数コンポーネントでシンプルに扱えるようになりました。

useRefとは

関数コンポーネントでは、Classコンポーネント時のref属性の代わりに、useRefを使って要素への参照を行います。
またuseRefでは、useStateのようにコンポーネント内での値を保持することが出来ます。

構文

const refObject = useRef(initialValue)

//例
const number = useRef(100);
console.log(number.current); // 100

useRefは、.currentプロパティが渡された引数(初期値はinitialValue)をrefObjectへ返します。
この引数の値が書き換え可能な.currentプロパティーの値であり、 .currentプロパティ内に保持することができます。

DOMを参照したい場合

const inputElement = useRef(null)

//例
<input ref={inputElement} type="text" />
console.log(inputElement); // current: null
DOMの参照例

useRefでrefオブジェクトを作成したものをref属性(HTML要素)に指定してDOMを参照しています。

const App = () => {
  const inputEl = useRef(null);
  const handleClick = () => {
    inputEl.current.focus();
    console.log("inputEl.current:", inputEl.current);
    //inputEl.current: <input type="text">
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={handleClick}>入力エリアをフォーカスする</button>
    </>
  );
};

ボタンクリックで<input type="text">がfocusされました。

参照:React公式サイト

useRefとuseStateをくらべてみる

useRefを使ってDOMを参照

useRefを利用するとtextのstate更新時にのみコンポーネントの再描画が発生します。

const App = () => {
  const inputEl = useRef(null);
  const [text, setText] = useState("");
  const handleClick = () => {
    setText(inputEl.current.value);
  };
  console.log("描画!!");
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={handleClick}>set text</button>
      <p>テキスト : {text}</p>
    </>
  );
};

useStateを使ってDOMを参照

入力中の文字列をステートinputElementに格納、ボタンが押された時にsetText(inputElement)textstateへ代入することでuseRefを使った時と同じ挙動にしています。この場合、textinputElementのstate更新時の両方でコンポーネントの再描画が発生しています。

const App = () => {
  const [inputElement, setInputElement] = useState("");
  const [text, setText] = useState("");
  const handleClick = () => {
    setText(inputElement);
  };
  console.log("描画!!");
  return (
    <>
      <input
        value={inputElement}
        onChange={(e) => setInputElement(e.target.value)}
        type="text"
      />
      <button onClick={handleClick}>setText</button>
      <p>テキスト : {text}</p>
    </>
  );
};

useStateを利用している場合はstateの変更される度にコンポーネントの再描画が発生しますが、useRefは値が変更になっても、コンポーネントの再描画が発生しません。useRefを利用するかどうかの判断基準のひとつは、コンポーネントの再描画が発生するかどうかで良さそうです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

create-react-appでReact(+Material-UI V4)の開発環境を準備する

create-react-appでReact(+Material-UI V4)の開発環境を準備した時のメモ

create-react-appって何?

create-react-appはFacebookが公開したReactの環境構築ツールで、Reactを利用した開発環境を簡単に作成することが出来る。

Create React Appをインストール

Create React Appのインストールはnode及びnpmの環境が必要で、バージョンが適合しないとインストール出来ないので注意。パッケージマネージャーにyarnも利用したいのでインストールしておいた。

node -vコマンドでnodeのバージョンが表示してみる。

$ node -v
//nodeのバージョンが表示される
v14.15.1

//yarnをグローバルにインストール
$ npm install -g yarn

$ yarn -v
//yarnのバージョンが表示される
1.7.0

node公式サイトから安定版をインストールできる。LTSがついているversionが安定版。

$ npx create-react-app react-practice
$ cd react-practice
$ yarn start

react-practiceの部分は任意のディレクトリ名(プロジェクト名)。
作成したreact-practiceに移動し、yarn startで作成したアプリを起動。

http://localhost:3000/にアクセスして次の画面が表示されていればインストール成功。
バージョン指定なしインストールしたら最新版(2020/11現在)V17.0.1であることを確認。
あっという間に開発環境ができた:hugging:

初期ファイル構成 画面
  • public/index.html はページテンプレート
  • src/index.js はJavaScriptのentryPoint
  • srcディレクトリはソースコードが配置されており、開発ではsrc以下のファイルを編集。
  • src/App.js は初期画面表示のAppコンポーネントが作成さている。

src/App.jsの中身(初期状態)は以下。

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

まずはsrc/App.jsを編集していくことで表示内容を変更してみる。不要そうなファイルを削除して開発準備完了。

参考: Create React App公式

簡単な表示テストをしてみる

まずは不要なロゴを削除し、src/App.js と src/App.css を編集。

react-practice
├── public
│   ├── logo192.png <= 削除 ×
│   ├── logo512.png <= 削除 ×
└── src
    ├── App.css   <= 編集 Material UIを追加後不要なので削除した
    ├── App.js    <= 編集
    ├── theme.js  <= Material UI用に追加
    ├── reportWebVitals.js  <= 削除 × 計測ツール、今回は不要なので削除した
    └── logo.svg  <= 削除 ×
App.jsx
import './App.css';

const App = () => {
  return (
    <div className="App">
      準備完了しました
    </div>
  );
}

export default App;
.App {
  text-align: center;
}

保存したタイミングでブラウザがリロードされ、文字列が 「準備完了!」に変更される。

こんな感じ。

Material-UIって何?

web開発をより高速かつ簡単なものにするGoogleMaterialデザインをベースに開発されたReactコンポーネントライブラリ。
手軽にMaterialDesignを取り入ることが出来、用意された多くのコンポーネントを組み合わせるだけで、デザイン工数をかけることなく見栄えのするサイトを構築出来る。

Material-UIをinstall

Material-UIをinstallしたら、公式ページで使いたいコンポーネントをすぐ見つけられるし、勝手にスタイリングしてくれるからテンションあがる?

$ yarn add @material-ui/core

Material Iconsも使いたい。
表示が早くてキレイなSVGアイコンを利用できる。

$ yarn add @material-ui/icons

参考: Material-UI公式

theme.jsの作成例

サイト全体のベースになるテーマを作成

import { createMuiTheme } from '@material-ui/core/styles';

// サイトのベースとなる独自のテーマを作成する
const theme = createMuiTheme({
  palette: {
    primary: {
      main: '#1976d2', //サイト内で使える任意のprimary color
    },
    secondary: {
      main: '#dc004e',//サイト内で使える任意のsecondary color
    },
    background: {
      default: '#fffafa', // 背景色を設定出来る。何も設定しなければ白
    },
  },
  typography: {
    fontFamily: [
      'sans-serif',
    ].join(','),
    fontSize: 12,
    h1: {
      fontSize: "1.75rem"
    },
    h2: {
      fontSize: "1.5rem"
    },
    h3: {
      fontSize: "1.25rem"
    },
    h4: {
      fontSize: "1.125rem"
    },
    h5: {
      fontSize: "1rem"
    },
    h6: {
      fontSize: "1rem"
    },
  }
});

export default theme;

index.jsの作成例

import React from 'react';
import ReactDOM from 'react-dom';
import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import './index.css';
import App from './App';
import theme from './theme'; //作成した独自テーマをimport

ReactDOM.render(
  <ThemeProvider theme={theme}> {/*サイト全体でthemeを利用できるようにする*/}
    <CssBaseline /> {/*サイト全体で表示差異をなくして一貫性をもたせる*/}
    <App />
  </ThemeProvider>,
  document.getElementById('root')
);

CssBaselineブラウザ間の表示差異をなくして一貫性をもたせる。いわゆるnormalize.cssの役割。

参考: css-baseline

App.jsの作成例

import React from 'react'
import { makeStyles, createStyles } from '@material-ui/core/styles';
// 使いたいMaterial UIのコンポーネントをimport
import {Container, Box, Typography, Button, ButtonGroup} from '@material-ui/core';
// 使いたいMaterial Iconsをimport
import FavoriteIcon from '@material-ui/icons/Favorite';

// スタイルを適用する
// 引数に作成したthemeを受け取る
const useStyles = makeStyles((theme) =>({
    root: {
      padding: theme.spacing(2),
      textAlign: 'center',
    },
  }))

const App = () => {
  const classes = useStyles()
  return (
    <Container maxWidth="lg" className={classes.root}>
      <Typography variant="h1" component="h1">
        <FavoriteIcon color="secondary"/>
          Material UIも準備完了
        <FavoriteIcon color="secondary"/>
      </Typography>
      <Box m={4} >
        <Typography variant="body1" >
          ここにコンテンツが入ります。
        </Typography>
      </Box>
      <ButtonGroup color="primary" aria-label="outlined button group">
        <Button variant="contained" color="primary">Primary</Button>
        <Button variant="contained" color="secondary">Secondary</Button>
      </ButtonGroup>
    </Container>
  );
}

export default App;

見た目はこんな感じになった。

App.jsで使ったコンポーネント例

各コンポーネントのAPIドキュメントで、CSSカスタマイズポイントや使い方などが書かれている。

用意されているコンポーネントを組み合わせて、最速でReactサイトを構築できそう:heart_eyes_cat:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む