- 投稿日:2020-10-20T17:12:04+09:00
Qiita開発チームがReactの開発で default export を使わなくなった理由
はじめに
こんにちは、Qiita開発チームの@ohakutsuです。
現在、QiitaのフロントエンドはReact + Atomic Designで実装されています。
Atomic Designの特徴として、再利用可能な単位で分割されたコンポーネントをつくる必要があります。
しかし、分割されたコンポーネントの数は日々大きくなっていってしまい、コンポーネントの管理が難しくなってしまいます。
そこで、Qiita開発チームでは、default export
を使い実装をしていたのをやめ、named export
を使い実装を行うようになりました。
今回は、Qiita開発チームがなぜdefault export
を使わなくなったのかについてお話します。なぜ default export を使わなくなったのか
Qiita開発チームが
default export
を使わなくなった理由は、default exportだとimportする側で自由に名前を決められてしまうためです。default exportを使った場合
.jsxexport default () => { ... }index.jsximport Button from './Button' // ↑↓自由に名前をつけることができてしまう import SubmitButton from './SubmitButton' ...このように、default exportにしてしまうと、import側で自由に名前をつけることができてしまい、コンポーネント名が統一されなくなってしまいます。
また、例に出した
SubmitButton
を抽象化し、Button
にした場合、ファイルパスはVSCodeなどで自動的に修正をしてくれますが、SubmitButton
→Button
にはなりません。ここで、実際の実装と定義名が異なってしまいます。また、それだけではなく、異なっていたとしても動いてしまうため、発見が難しくなるといったこともあります。named exportを使った場合
SubmitButton.jsxexport const SubmitButton = () => { ... }index.jsximport { SubmitButton } from './SubmitButton' ...named exportの場合、importする側ではexport側で定義された名前をそのまま使うことになります。
また、以下のようにコンポーネント名を変更した場合、Button.jsxexport const Button = () => { ... }
Submitbutton
をインポートしている側でエラーが起きます。index.jsximport { SubmitButton } from './Button' // ←エラーになる ...エラーが起きるため、インポート側でのコンポーネント名の変更忘れに気づくことができます。
冒頭でもお話しましたが、Atomic Designでは、部品ごとにパーツを作り、さらに組み立てたコンポーネントをつくっていくため、どうしてもコンポーネントの数が多くなってしまいます。そこで
default export
を使うと、コードを書く人によってコンポーネント名が変わる可能性があり、コンポーネントの管理が難しくなるといった問題が考えられます。
そのため、named export
でインポートするコンポーネント名に制限をし、コンポーネントの管理をしやすくしたというのも1つの理由です。named exportにしたときの問題点
React.lazy
はdefault exportでないと使えないCode-Splitting – React によると、
React.lazy
はnamed exportには対応しておらず、ManyComponents.jsexport const MyComponent = /* ... */; export const MyUnusedComponent = /* ... */;MyComponent.jsexport { MyComponent as default } from "./ManyComponents.js";MyApp.jsimport React, { lazy } from 'react'; const MyComponent = lazy(() => import("./MyComponent.js"));のように、
named export
->default export
にするための中間コンポーネントが必要になります。
React.lazy
を使う必要のあるコンポーネントの場合は、例外としてディレクトリを分けるなどして、default export
で実装するのもアリだと思います。さいごに
Qiita開発チームでAtomic Designを行う際に、
default export
を使わなくなった理由について書いてきました。
僕はまだQiita開発チームに来て4ヶ月程度しかたっておらず、まだまだ力不足ですが、これからもQiitaをよりよいものにしていくために、開発・改善を行っていきます。また、Qiitaの質問に
default export
/named export
についての意見交換を投稿しているので、ぜひ、ご意見をお聞かせください。
[意見交換] React開発で使うならnamed export?default export? - Qiita
- 投稿日:2020-10-20T15:55:00+09:00
Recoil公式ドキュメント 翻訳⑦ Selectors
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
Selector
selectorは、divider state (派生状態)を表します。divider stateは、与えられたstateを何らかの方法で変更する純粋な関数にstateを渡す出力と考えることができます。
派生stateは、他のデータに依存する動的データを構築できるため、強力な概念です。todoリストアプリケーションのコンテキストでは、次のものが派生stateと見なされます。
フィルタされたtodoリスト:いくつかの基準(すでに完了している項目を除外するなど)に基づいてフィルタされた特定の項目を持つ新しいリストを作成することによって、完全なtodoリストから派生します。
ToDoリストの統計:リスト内の項目の総数、完了した項目の数、完了した項目の割合など、リストの有用な属性を計算することによって、完全なToDoリストから得られます。
フィルタされたtodoリストを実装するには、atomに値を保存できる一連のフィルタ条件を選択する必要があります。
使用するフィルタオプションは、「すべて表示」、「完了を表示」、および「未完了を表示」です。デフォルト値は「すべて表示」です。const todoListFilterState = atom({ key: 'todoListFilterState', default: 'Show All', });
todoListFilterState
とtodoListState
を使用して、フィルタされたリストを導出するfilteredTodoListState
selectorを構築できます。const filteredTodoListState = selector({ key: 'filteredTodoListState', get: ({get}) => { const filter = get(todoListFilterState); const list = get(todoListState); switch (filter) { case 'Show Completed': return list.filter((item) => item.isComplete); case 'Show Uncompleted': return list.filter((item) => !item.isComplete); default: return list; } }, });
filteredTodoListState
は内部的に2つの依存関係 (todoListFilterState
とtodoListState
) を追跡し、どちらかが変更された場合に再実行されるようにします。コンポーネントの観点から見ると、selectorは、atomを読み取るために使用されるのと同じhookを使用して読み取ることができます。ただし、一部のhookは書き込み可能なstate(i.e
useRecoilState()
)でのみ機能することに注意してください。
全てのatomは書き込み可能stateであるが、書き込み可能stateとみなされるのは一部のselectorのみである(get
プロパティとset
プロパティの両方を持つselector)。このトピックの詳細は、コアコンセプトを参照してください。フィルタリングされたtodoListの表示は、TodoListコンポーネントで1行変更するだけです。
function TodoList() { // changed from todoListState to filteredTodoListState const todoList = useRecoilValue(filteredTodoListState); return ( <> <TodoListStats /> <TodoListFilters /> <TodoItemCreator /> {todoList.map((todoItem) => ( <TodoItem item={todoItem} key={todoItem.id} /> ))} </> ); }
todoListFilterState
にデフォルト値「すべて表示(Show All)」が指定されているため、UIはすべてのtodoを表示していることに注意してください。
フィルタを変更するには、TodoListFilters
コンポーネントを実装する必要があります。function TodoListFilters() { const [filter, setFilter] = useRecoilState(todoListFilterState); const updateFilter = ({target: {value}}) => { setFilter(value); }; return ( <> Filter: <select value={filter} onChange={updateFilter}> <option value="Show All">All</option> <option value="Show Completed">Completed</option> <option value="Show Uncompleted">Uncompleted</option> </select> </> ); }数行のコードでフィルタリングを実装することができました!
同じ概念を使用して、TodoListStats
コンポーネントを実装します。次の統計を表示します。
- todo項目の合計数
- 完了項目の合計数
- 未完了項目の総数
- 達成率
統計情報ごとにselectorを作成することもできますが、より簡単な方法は、必要なデータを含むオブジェクトを返すselectorを1つ作成することです。このselectorを
doListStatsState
と呼びます。const todoListStatsState = selector({ key: 'todoListStatsState', get: ({get}) => { const todoList = get(todoListState); const totalNum = todoList.length; const totalCompletedNum = todoList.filter((item) => item.isComplete).length; const totalUncompletedNum = totalNum - totalCompletedNum; const percentCompleted = totalNum === 0 ? 0 : totalCompletedNum / totalNum; return { totalNum, totalCompletedNum, totalUncompletedNum, percentCompleted, }; }, });
todoListStatsState
の値を読み取るには、もう一度useRecoilValue()
を使用します。function TodoListStats() { const { totalNum, totalCompletedNum, totalUncompletedNum, percentCompleted, } = useRecoilValue(todoListStatsState); const formattedPercentCompleted = Math.round(percentCompleted * 100); return ( <ul> <li>Total items: {totalNum}</li> <li>Items completed: {totalCompletedNum}</li> <li>Items not completed: {totalUncompletedNum}</li> <li>Percent completed: {formattedPercentCompleted}</li> </ul> ); }まとめると、私たちはすべての要件を満たすtodoリストアプリを作成しました。
- todo項目を追加する
- todo項目を編集する
- todo項目を削除する
- todo項目をフィルタする
- 有用な統計を表示
参考サイト
全目次
- 投稿日:2020-10-20T15:55:00+09:00
Recoil公式ドキュメント 翻訳⑦ 基本チュートリアル-Selectors
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
Selector
selectorは、divider state (派生状態)を表します。divider stateは、与えられたstateを何らかの方法で変更する純粋な関数にstateを渡す出力と考えることができます。
派生stateは、他のデータに依存する動的データを構築できるため、強力な概念です。todoリストアプリケーションのコンテキストでは、次のものが派生stateと見なされます。
フィルタされたtodoリスト:いくつかの基準(すでに完了している項目を除外するなど)に基づいてフィルタされた特定の項目を持つ新しいリストを作成することによって、完全なtodoリストから派生します。
ToDoリストの統計:リスト内の項目の総数、完了した項目の数、完了した項目の割合など、リストの有用な属性を計算することによって、完全なToDoリストから得られます。
フィルタされたtodoリストを実装するには、atomに値を保存できる一連のフィルタ条件を選択する必要があります。
使用するフィルタオプションは、「すべて表示」、「完了を表示」、および「未完了を表示」です。デフォルト値は「すべて表示」です。const todoListFilterState = atom({ key: 'todoListFilterState', default: 'Show All', });
todoListFilterState
とtodoListState
を使用して、フィルタされたリストを導出するfilteredTodoListState
selectorを構築できます。const filteredTodoListState = selector({ key: 'filteredTodoListState', get: ({get}) => { const filter = get(todoListFilterState); const list = get(todoListState); switch (filter) { case 'Show Completed': return list.filter((item) => item.isComplete); case 'Show Uncompleted': return list.filter((item) => !item.isComplete); default: return list; } }, });
filteredTodoListState
は内部的に2つの依存関係 (todoListFilterState
とtodoListState
) を追跡し、どちらかが変更された場合に再実行されるようにします。コンポーネントの観点から見ると、selectorは、atomを読み取るために使用されるのと同じhookを使用して読み取ることができます。ただし、一部のhookは書き込み可能なstate(i.e
useRecoilState()
)でのみ機能することに注意してください。
全てのatomは書き込み可能stateであるが、書き込み可能stateとみなされるのは一部のselectorのみである(get
プロパティとset
プロパティの両方を持つselector)。このトピックの詳細は、コアコンセプトを参照してください。フィルタリングされたtodoListの表示は、TodoListコンポーネントで1行変更するだけです。
function TodoList() { // changed from todoListState to filteredTodoListState const todoList = useRecoilValue(filteredTodoListState); return ( <> <TodoListStats /> <TodoListFilters /> <TodoItemCreator /> {todoList.map((todoItem) => ( <TodoItem item={todoItem} key={todoItem.id} /> ))} </> ); }
todoListFilterState
にデフォルト値「すべて表示(Show All)」が指定されているため、UIはすべてのtodoを表示していることに注意してください。
フィルタを変更するには、TodoListFilters
コンポーネントを実装する必要があります。function TodoListFilters() { const [filter, setFilter] = useRecoilState(todoListFilterState); const updateFilter = ({target: {value}}) => { setFilter(value); }; return ( <> Filter: <select value={filter} onChange={updateFilter}> <option value="Show All">All</option> <option value="Show Completed">Completed</option> <option value="Show Uncompleted">Uncompleted</option> </select> </> ); }数行のコードでフィルタリングを実装することができました!
同じ概念を使用して、TodoListStats
コンポーネントを実装します。次の統計を表示します。
- todo項目の合計数
- 完了項目の合計数
- 未完了項目の総数
- 達成率
統計情報ごとにselectorを作成することもできますが、より簡単な方法は、必要なデータを含むオブジェクトを返すselectorを1つ作成することです。このselectorを
doListStatsState
と呼びます。const todoListStatsState = selector({ key: 'todoListStatsState', get: ({get}) => { const todoList = get(todoListState); const totalNum = todoList.length; const totalCompletedNum = todoList.filter((item) => item.isComplete).length; const totalUncompletedNum = totalNum - totalCompletedNum; const percentCompleted = totalNum === 0 ? 0 : totalCompletedNum / totalNum; return { totalNum, totalCompletedNum, totalUncompletedNum, percentCompleted, }; }, });
todoListStatsState
の値を読み取るには、もう一度useRecoilValue()
を使用します。function TodoListStats() { const { totalNum, totalCompletedNum, totalUncompletedNum, percentCompleted, } = useRecoilValue(todoListStatsState); const formattedPercentCompleted = Math.round(percentCompleted * 100); return ( <ul> <li>Total items: {totalNum}</li> <li>Items completed: {totalCompletedNum}</li> <li>Items not completed: {totalUncompletedNum}</li> <li>Percent completed: {formattedPercentCompleted}</li> </ul> ); }まとめると、私たちはすべての要件を満たすtodoリストアプリを作成しました。
- todo項目を追加する
- todo項目を編集する
- todo項目を削除する
- todo項目をフィルタする
- 有用な統計を表示
参考サイト
全目次
- 投稿日:2020-10-20T15:16:31+09:00
Recoil公式ドキュメント 翻訳⑥ Atoms
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
Atom
atomには、アプリケーションstateの信頼できる情報源(source)が含まれています。
このtodoリストでは、sourceはオブジェクトの配列であり、各オブジェクトはtodo項目を表します。リストatomを
todoListState
と呼び出し、atom()
関数を使用して作成します。const todoListState = atom({ key: 'todoListState', default: [], });atomに一意のkeyを与え、デフォルト値を空の配列に設定します。
このatomの内容を読み取るには、TodoListコンポーネントのuseRecoilValue()
hookを使用します。function TodoList() { const todoList = useRecoilValue(todoListState); return ( <> {/* <TodoListStats /> */} {/* <TodoListFilters /> */} <TodoItemCreator /> {todoList.map((todoItem) => ( <TodoItem key={todoItem.id} item={todoItem} /> ))} </> ); }コメントアウトされたコンポーネントは、次のセクションで実装されます。
新しいtodo項目を作成するには、
todoListState
の内容を更新する設定関数にアクセスする必要があります。
useSetRecoilState()
hookを使用して、TodoItemCreator
コンポーネントに設定関数を取得できます。function TodoItemCreator() { const [inputValue, setInputValue] = useState(''); const setTodoList = useSetRecoilState(todoListState); const addItem = () => { setTodoList((oldTodoList) => [ ...oldTodoList, { id: getId(), text: inputValue, isComplete: false, }, ]); setInputValue(''); }; const onChange = ({target: {value}}) => { setInputValue(value); }; return ( <div> <input type="text" value={inputValue} onChange={onChange} /> <button onClick={addItem}>Add</button> </div> ); } // utility for creating unique Id let id = 0; function getId() { return id++; }古いtodoリストに基づいて新しいtodoリストを作成できるように、設定関数のupdater形式を使用していることに注意してください。
TodoItem
コンポーネントは、todo項目の値を表示しますが、そのテキストを変更したり項目を削除したりすることもできます。todoListState
を読み取って、項目テキストを更新し、完了としてマークし、削除するために使用する設定関数を取得するには、useRecoilState()
を使用します。function TodoItem({item}) { const [todoList, setTodoList] = useRecoilState(todoListState); const index = todoList.findIndex((listItem) => listItem === item); const editItemText = ({target: {value}}) => { const newList = replaceItemAtIndex(todoList, index, { ...item, text: value, }); setTodoList(newList); }; const toggleItemCompletion = () => { const newList = replaceItemAtIndex(todoList, index, { ...item, isComplete: !item.isComplete, }); setTodoList(newList); }; const deleteItem = () => { const newList = removeItemAtIndex(todoList, index); setTodoList(newList); }; return ( <div> <input type="text" value={item.text} onChange={editItemText} /> <input type="checkbox" checked={item.isComplete} onChange={toggleItemCompletion} /> <button onClick={deleteItem}>X</button> </div> ); } function replaceItemAtIndex(arr, index, newValue) { return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)]; } function removeItemAtIndex(arr, index) { return [...arr.slice(0, index), ...arr.slice(index + 1)]; }これで、完全に機能するToDoリストができました!
次のセクションでは、selectorを使用してリストを次のレベルアップする方法について説明します。
参考サイト
全目次
- 投稿日:2020-10-20T15:16:31+09:00
Recoil公式ドキュメント 翻訳⑥ 基本チュートリアル-Atoms
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
Atom
atomには、アプリケーションstateの信頼できる情報源(source)が含まれています。
このtodoリストでは、sourceはオブジェクトの配列であり、各オブジェクトはtodo項目を表します。リストatomを
todoListState
と呼び出し、atom()
関数を使用して作成します。const todoListState = atom({ key: 'todoListState', default: [], });atomに一意のkeyを与え、デフォルト値を空の配列に設定します。
このatomの内容を読み取るには、TodoListコンポーネントのuseRecoilValue()
hookを使用します。function TodoList() { const todoList = useRecoilValue(todoListState); return ( <> {/* <TodoListStats /> */} {/* <TodoListFilters /> */} <TodoItemCreator /> {todoList.map((todoItem) => ( <TodoItem key={todoItem.id} item={todoItem} /> ))} </> ); }コメントアウトされたコンポーネントは、次のセクションで実装されます。
新しいtodo項目を作成するには、
todoListState
の内容を更新する設定関数にアクセスする必要があります。
useSetRecoilState()
hookを使用して、TodoItemCreator
コンポーネントに設定関数を取得できます。function TodoItemCreator() { const [inputValue, setInputValue] = useState(''); const setTodoList = useSetRecoilState(todoListState); const addItem = () => { setTodoList((oldTodoList) => [ ...oldTodoList, { id: getId(), text: inputValue, isComplete: false, }, ]); setInputValue(''); }; const onChange = ({target: {value}}) => { setInputValue(value); }; return ( <div> <input type="text" value={inputValue} onChange={onChange} /> <button onClick={addItem}>Add</button> </div> ); } // 一意のIDを作成するためのユーティリティ let id = 0; function getId() { return id++; }古いtodoリストに基づいて新しいtodoリストを作成できるように、設定関数のupdater形式を使用していることに注意してください。
TodoItem
コンポーネントは、todo項目の値を表示しますが、そのテキストを変更したり項目を削除したりすることもできます。todoListState
を読み取って、項目テキストを更新し、完了としてマークし、削除するために使用する設定関数を取得するには、useRecoilState()
を使用します。function TodoItem({item}) { const [todoList, setTodoList] = useRecoilState(todoListState); const index = todoList.findIndex((listItem) => listItem === item); const editItemText = ({target: {value}}) => { const newList = replaceItemAtIndex(todoList, index, { ...item, text: value, }); setTodoList(newList); }; const toggleItemCompletion = () => { const newList = replaceItemAtIndex(todoList, index, { ...item, isComplete: !item.isComplete, }); setTodoList(newList); }; const deleteItem = () => { const newList = removeItemAtIndex(todoList, index); setTodoList(newList); }; return ( <div> <input type="text" value={item.text} onChange={editItemText} /> <input type="checkbox" checked={item.isComplete} onChange={toggleItemCompletion} /> <button onClick={deleteItem}>X</button> </div> ); } function replaceItemAtIndex(arr, index, newValue) { return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)]; } function removeItemAtIndex(arr, index) { return [...arr.slice(0, index), ...arr.slice(index + 1)]; }これで、完全に機能するToDoリストができました!
次のセクションでは、selectorを使用してリストを次のレベルアップする方法について説明します。
参考サイト
全目次
- 投稿日:2020-10-20T14:00:18+09:00
Recoil公式ドキュメント 翻訳⑤ 概要
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
概要
このセクション(基本チュートリアル)では、RecoilとReactがインストールされていることを前提としています。
RecoilとReactをゼロから始める方法については、入門を参照してください。
以下のセクションのコンポーネントは、親ツリーに<RecoilRoot />
があるものとします。このチュートリアルでは、単純なToDoリストアプリケーションを作成します。
私たちのアプリは以下のことができます。
- todo項目を追加する
- todo項目を編集する
- todo項目を削除する
- todo項目をフィルタする
- 有用な統計を表示
その過程で、atom、selector、atom families、そしてRecoil APIによって公開されるhooksについて説明します。
参考サイト
全目次
- 投稿日:2020-10-20T14:00:18+09:00
Recoil公式ドキュメント 翻訳⑤ 基本チュートリアル-概要
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
概要
このセクション(基本チュートリアル)では、RecoilとReactがインストールされていることを前提としています。
RecoilとReactをゼロから始める方法については、入門を参照してください。
以下のセクションのコンポーネントは、親ツリーに<RecoilRoot />
があるものとします。このチュートリアルでは、単純なToDoリストアプリケーションを作成します。
私たちのアプリは以下のことができます。
- todo項目を追加する
- todo項目を編集する
- todo項目を削除する
- todo項目をフィルタする
- 有用な統計を表示
その過程で、atom、selector、atom families、そしてRecoil APIによって公開されるhooksについて説明します。
参考サイト
全目次
- 投稿日:2020-10-20T12:17:08+09:00
React/Redux初心者が参考にしたい教材集
はじめに
業務でReact/Reduxを使うことになったものの、キャッチアップコストが高い割りに初心者向けの書籍はあまり世に出てない印象を受けました。
そこで自分が参考にした教材たちを書き残しておきたいと思います。最初の一歩
progate
安定のprogate先輩。ハマりがちな環境構築もないので、まずはこちらでReactに触れてみるのが良いでしょう。(要課金)
JSに不安のある方は合わせてES2015も合わせてやっておくと吉。
https://prog-8.com/languages/reactReactでReduxを使ってみよう Kindle版
Reduxについて初心者向けに1行1行説明してくれておりわかりやすいです。
https://www.amazon.co.jp/dp/B07P7DBLBL/ref=cm_sw_em_r_mt_dp_4nLJFbGJCPMD7慣れてきたら
最短で学ぶReactとReduxの基礎から実践まで
ライブラリやAPIを使いながらReact+Reduxで動く物を作れますし、説明もわかりやすいです。ただ、若干古めな教材なので環境構築で少し手こずりました。(JSはほんと移り変わりが早いですね)
https://www.udemy.com/share/101YJ4AEAZdV5TTHkH/【はむ式】フロントエンドエンジニアのための React ・ Redux アプリケーション開発入門
こちらも一通りのものを作れますが、「最短で学ぶReactとReduxの基礎から実践まで」よりはちょっと難しい印象です。
https://www.udemy.com/share/1021hGAEAZdV5TTHkH/
- 投稿日:2020-10-20T10:36:30+09:00
【React④】Props
Propsとは
- Propsとはコンポネントの属性、あるデータの属性で参照できるもののこと
- {}で囲って渡していく
- 受けわたせるデータ型は文字列、数値、真偽、配列、オブジェクト、変数などなんでも
- 文字列は{}なしでもok
- 例えばUserのComponentに対してnameというPropsを与えることができる
keyの指定
ReactではバーチャルDOMでどのDOMが変更されたかを管理し、変更点のみ実際のDOMに反映している。
key={index}
のようにそれぞれのDOMにkeyを与えてあげることで必要最低限なDOM範囲を管理している//エラー文 array,iterator should have a unique "key" prop.import React from 'react'; const App = () =>{ const profiles = [ { name:"Taro", age:10 }, { name:"Hanako", age: 5 }, { name:"Noname" } ] return ( <div> { profiles.map((profile,index) => { return <User name={profile.name} age={profile.age} key={index}/> }) } </div> ) } //外からの入力を参照して画面に出力することができる const User = (props) =>{ return <div>Hi!, I am {props.name},and {props.age} years old! </div> } //ageが入力されなかったときにage1がデフォルト値として1が渡される User.defaultProps ={ age:1 }Propsでデータを受け渡す
親コンポーネントから子コンポーネントにPropsデータを受け渡す。
Blog.jsx//親コンポーネント import React from 'React'; import Article from "./Article"; //title={"React"} が子コンポーネントに受け渡される class Blog extends React.Component{ constructor(props){ super(props); } render(){ return( <> <Article title={"React"} /> </> ) } } export default BlogArticle.jsximport React from 'React'; const Article = (props) =>{ return( <div> <h2>{props.title}</h2> </div> ) }; export default Articleいろんな型のデータを渡す
子コンポーネントに以下を渡します
title={"React"}
、order={3}
、isPublished={true}
、author={"authorName"}
Blog.jsximport React from 'React'; import Article from "./Article"; class Blog extends React.Component{ constructor(props){ super(props); } render(){ const authorName = "Facebook"; return( <> <Article title={"React"} order={3} isPublished={true} author={"authorName"} /> </> ) } } export default BlogArticle.jsximport React from 'React'; const Article = (props) =>{ let publishState =""; if (props.isPublished){ publishState = "公開" }else{ publishState = "非公開" } return( <div> <h2>{props.title}</p> <p>順番:{props.order}</p> <p>著者:{props.author}</p> <p>{publishState}</p> </div> ) }; export default Article再利用する
Blog.jsximport React from 'React'; import Article from "./Article"; class Blog extends React.Component{ constructor(props){ super(props); } render(){ const authorName = "Facebook"; return( <> <Article title={"React"} /> <Article title={"JSX"} /> <Article title={"Component"} /> <Article title={"Props"} /> </> ) } } export default Blog
- 投稿日:2020-10-20T08:57:22+09:00
【React③】Component
Componentとは
ComponentはUIを作成するためにあり、見た目(View)と機能(Controller)で成り立っている。
webの構造はComponentのツリー構造をしていて
headerのComponentのなかにnavigation、login のComponentが含まれる。
ReactではComponentを一個ずつ作ってWebアプリなどを構成する。Componentのメリット
- 再利用性
- 一つのComponentを作ると引数(Props)を渡すことができる
- 例:buttonというコンポネントからlogin、log-outボタンを作成できる
- 分割管理
- Component同士は疎結合なので、影響し合わない
- 修正変更、新機能追加が簡単
- 疎結合であることから、修正変更が必要なComponentのみ変更することができる
Componentの種類
- Class Component:クラスによって定義されたComponent
- React.Componentを継承
- constructorでpropsを初期化
- ライフサイクルやstateを持つ
- webページが表示されるときに生成され、ユーザの操作や次のページへの遷移すると消える
- propsにはthisが必要(このclass内のpropsを使うため)
- render内でJSXをreturn
- 最近推奨されてない
//App=Class Component import React, { Component } from 'react'; class App extends Component{ constructor(props){ super(props); } render() { return( <div> <h2>{this.props.title}</h2> </div> ); } }
- Functional Component:関数型で定義されたComponent
- ES6のアロー関数で記述
- stateを持たない
- propsを引数に受け取ることができる
- JSXをreturnする
//App=Functional Component import React from 'react'; //Functional Componentでは{Component}のimportは不要 const App = (props) =>{ return ( <div> <h2>{props.title}</h2> </div> ); }
- 投稿日:2020-10-20T02:41:59+09:00
Recoil公式ドキュメント 翻訳④ 前書き-入門
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
入門
Create React App
RecoilはReactの状態管理ライブラリであるため、Recoilを使用するには、Reactをインストールして実行する必要があります。Reactアプリケーションをブートストラップするための最も簡単で推奨される方法は、Create React Appを使用することです。
npx create-react-app my-app
npxはnpm5.2以降に付属するパッケージランナーツールです。古いnpmバージョンの手順を参照してください。
Create React Appをインストールするその他の方法については、公式ドキュメントを参照してください。
Installation
Recoilパッケージはnpmにあります。
最新の安定バージョンをインストールするには、次のコマンドを実行します。npm install recoil
yarnを使用している場合:
yarn add recoil
RecoilRoot
Recoil State を使用するコンポーネントでは、親ツリーのどこかにRecoilRootが表示される必要があります。
これはルートコンポーネントに置くとよいでしょう。import React from 'react'; import { RecoilRoot, atom, selector, useRecoilState, useRecoilValue, } from 'recoil'; function App() { return ( <RecoilRoot> <CharacterCounter /> </RecoilRoot> ); }次のセクションでは、
CharacterCounter
コンポーネントを実装します。Atom
Atomは
state
を表し、任意のコンポーネントから読み取りおよび書き込みを行うことができます。
Atomの値を読み取るコンポーネントは暗黙的にそのAtomに登録されているため、Atomを更新すると、そのAtomに登録されているすべてのコンポーネントが再レンダリングされます。const textState = atom({ key: 'textState', // unique ID (他の atoms/selectors に関して) default: '', // default value (初期値として) });Atomからの読み取りとAtomへの書き込みが必要なコンポーネントは、
useRecoilState()
以下に示すように使用する必要があります。function CharacterCounter() { return ( <div> <TextInput /> <CharacterCount /> </div> ); } function TextInput() { const [text, setText] = useRecoilState(textState); const onChange = (event) => { setText(event.target.value); }; return ( <div> <input type="text" value={text} onChange={onChange} /> <br /> Echo: {text} </div> ); }Selector
Selectorは、派生状態(derived state)を表します。派生stateは state の変換を行います。
指定された状態を何らかの方法で変換する純粋関数に状態を渡す出力と考えることができます。const charCountState = selector({ key: 'charCountState', // unique ID (他の atoms/selectors に関して) get: ({get}) => { const text = get(textState); return text.length; }, });
useRecoilValue()
フックを使用して、charCountState
の値を読み取ることができます。function CharacterCount() { const count = useRecoilValue(charCountState); return <>Character Count: {count}</>; }
参考サイト
・公式ドキュメント
・Create React App
・npx
・古いnpmバージョンの手順
・npm
・yarn
・Pure function (純粋関数)とは
・みらい翻訳
・Demoのリポジトリ ディレクトリ構成の参考に(なるかわかりませんが)どうぞ
全目次
- 投稿日:2020-10-20T02:41:59+09:00
Recoil公式ドキュメント 翻訳④ 入門
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
入門
Create React App
RecoilはReactの状態管理ライブラリであるため、Recoilを使用するには、Reactをインストールして実行する必要があります。Reactアプリケーションをブートストラップするための最も簡単で推奨される方法は、Create React Appを使用することです。
npx create-react-app my-app
npxはnpm5.2以降に付属するパッケージランナーツールです。古いnpmバージョンの手順を参照してください。
Create React Appをインストールするその他の方法については、公式ドキュメントを参照してください。
Installation
Recoilパッケージはnpmにあります。
最新の安定バージョンをインストールするには、次のコマンドを実行します。npm install recoil
yarnを使用している場合:
yarn add recoil
RecoilRoot
Recoil State を使用するコンポーネントでは、親ツリーのどこかにRecoilRootが表示される必要があります。
これはルートコンポーネントに置くとよいでしょう。import React from 'react'; import { RecoilRoot, atom, selector, useRecoilState, useRecoilValue, } from 'recoil'; function App() { return ( <RecoilRoot> <CharacterCounter /> </RecoilRoot> ); }次のセクションでは、
CharacterCounter
コンポーネントを実装します。Atom
Atomは
state
を表し、任意のコンポーネントから読み取りおよび書き込みを行うことができます。
Atomの値を読み取るコンポーネントは暗黙的にそのAtomに登録されているため、Atomを更新すると、そのAtomに登録されているすべてのコンポーネントが再レンダリングされます。const textState = atom({ key: 'textState', // unique ID (他の atoms/selectors に関して) default: '', // default value (初期値として) });Atomからの読み取りとAtomへの書き込みが必要なコンポーネントは、
useRecoilState()
以下に示すように使用する必要があります。function CharacterCounter() { return ( <div> <TextInput /> <CharacterCount /> </div> ); } function TextInput() { const [text, setText] = useRecoilState(textState); const onChange = (event) => { setText(event.target.value); }; return ( <div> <input type="text" value={text} onChange={onChange} /> <br /> Echo: {text} </div> ); }Selector
Selectorは、
derived state
(派生状態?)を表します。derived state
はstate
の変換です。
指定された状態を何らかの方法で変換する純粋関数に状態を渡す出力と考えることができます。const charCountState = selector({ key: 'charCountState', // unique ID (他の atoms/selectors に関して) get: ({get}) => { const text = get(textState); return text.length; }, });
useRecoilValue()
フックを使用して、charCountState
の値を読み取ることができます。function CharacterCount() { const count = useRecoilValue(charCountState); return <>Character Count: {count}</>; }
参考サイト
・公式ドキュメント
・Create React App
・npx
・古いnpmバージョンの手順
・npm
・yarn
・Pure function (純粋関数)とは
・みらい翻訳
全目次
- 投稿日:2020-10-20T02:25:30+09:00
Recoil公式ドキュメント 翻訳③
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
インストール
NPM
Recoilパッケージはnpmとyarnにあります。
最新の安定版をインストールするには、次のコマンドを実行します。npmを使用している場合:
npm install recoil
yarnを使用している場合:
yarn add recoil
Bundler
NPMを介してインストールされたRecoilは、WebpackやRollupなどのモジュールバンドラーとうまく組み合わせられます。
ES 5サポート
RecoilビルドはES 5にトランスパイルされず、ES 5でのRecoilの使用はサポートされていません。
ES 6を基本として提供していないブラウザをサポートする必要がある場合は、Babelでコードをコンパイルし、preset@babel/preset-envを使用してください。
ただし、これはサポートされていないため、問題が発生する可能性があります。特に、Reactと同様に、Recoilは、ES 6の
Map
とSet
のタイプやその他の機能に依存します。polyfillsを使用してこれらの機能をエミュレートすると、パフォーマンスが大幅に低下する可能性があります。CDN
バージョン0.0 .11以降、Recoilは
<script>
タグで直接使用できるUMDビルドを提供し、シンボルRecoilをグローバルネームスペースに公開しています。新しいバージョンからの予期しない破損を避けるために、特定のバージョン番号とビルドにリンクすることをお勧めします。<script src="https://cdn.jsdelivr.net/npm/recoil@0.0.11/umd/recoil.production.js"></script>CDN上のすべてのRecoilファイルは、jsdelivrで参照できます。
ESLint
プロジェクトでeslin-plugin-react-hooksを使用している場合。たとえば、次のようなeslint設定では、
// previous .eslint config { "plugins": [ "react-hooks" ], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } }
additionalHooks
のリストに'useRecoilCallback'を追加することをお勧めします。
この変更により、ESLintはuseRecoilCallback()
に渡された依存関係が誤って指定された場合に警告を出し、修正を提案します。
additionalHooks
のフォーマットは正規表現の文字列です。// modified .eslint config { "plugins": [ "react-hooks" ], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": [ "warn", { "additionalHooks": "useRecoilCallback" } ] } }
参考サイト
・公式ドキュメント
・npm
・yarn
・Webpack
・Rollup
・Babel
・preset@babel/preset-env
・jsdelivr
・eslin-plugin-react-hooks
・useRecoilCallback
・みらい翻訳
全目次
- 投稿日:2020-10-20T02:25:30+09:00
Recoil公式ドキュメント 翻訳③ 前書き-インストール
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
インストール
NPM
Recoilパッケージはnpmにあります。
最新の安定版をインストールするには、次のコマンドを実行します。npm install recoil
yarnを使用している場合:
yarn add recoil
Bundler
NPMを介してインストールされたRecoilは、WebpackやRollupなどのモジュールバンドラーとうまく組み合わせられます。
ES 5サポート
RecoilビルドはES 5にトランスパイルされず、ES 5でのRecoilの使用はサポートされていません。
ES 6を基本として提供していないブラウザをサポートする必要がある場合は、Babelでコードをコンパイルし、preset@babel/preset-envを使用してください。
ただし、これはサポートされていないため、問題が発生する可能性があります。特に、Reactと同様に、Recoilは、ES 6の
Map
とSet
のタイプやその他の機能に依存します。polyfillsを使用してこれらの機能をエミュレートすると、パフォーマンスが大幅に低下する可能性があります。CDN
バージョン0.0 .11以降、Recoilは
<script>
タグで直接使用できるUMDビルドを提供し、シンボルRecoilをグローバルネームスペースに公開しています。新しいバージョンからの予期しない破損を避けるために、特定のバージョン番号とビルドにリンクすることをお勧めします。<script src="https://cdn.jsdelivr.net/npm/recoil@0.0.11/umd/recoil.production.js"></script>CDN上のすべてのRecoilファイルは、jsdelivrで参照できます。
ESLint
プロジェクトでeslint-plugin-react-hooksを使用している場合。たとえば、次のようなeslint設定では、
// previous .eslint config { "plugins": [ "react-hooks" ], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } }
additionalHooks
のリストに'useRecoilCallback'を追加することをお勧めします。
この変更により、ESLintはuseRecoilCallback()
に渡された依存関係が誤って指定された場合に警告を出し、修正を提案します。
additionalHooks
のフォーマットは正規表現の文字列です。// modified .eslint config { "plugins": [ "react-hooks" ], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": [ "warn", { "additionalHooks": "useRecoilCallback" } ] } }
参考サイト
・公式ドキュメント
・npm
・yarn
・Webpack
・Rollup
・Babel
・preset@babel/preset-env
・jsdelivr
・eslint-plugin-react-hooks
・useRecoilCallback
・みらい翻訳
全目次
- 投稿日:2020-10-20T02:25:30+09:00
Recoil公式ドキュメント 翻訳③ インストール
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
インストール
NPM
Recoilパッケージはnpmにあります。
最新の安定版をインストールするには、次のコマンドを実行します。npm install recoil
yarnを使用している場合:
yarn add recoil
Bundler
NPMを介してインストールされたRecoilは、WebpackやRollupなどのモジュールバンドラーとうまく組み合わせられます。
ES 5サポート
RecoilビルドはES 5にトランスパイルされず、ES 5でのRecoilの使用はサポートされていません。
ES 6を基本として提供していないブラウザをサポートする必要がある場合は、Babelでコードをコンパイルし、preset@babel/preset-envを使用してください。
ただし、これはサポートされていないため、問題が発生する可能性があります。特に、Reactと同様に、Recoilは、ES 6の
Map
とSet
のタイプやその他の機能に依存します。polyfillsを使用してこれらの機能をエミュレートすると、パフォーマンスが大幅に低下する可能性があります。CDN
バージョン0.0 .11以降、Recoilは
<script>
タグで直接使用できるUMDビルドを提供し、シンボルRecoilをグローバルネームスペースに公開しています。新しいバージョンからの予期しない破損を避けるために、特定のバージョン番号とビルドにリンクすることをお勧めします。<script src="https://cdn.jsdelivr.net/npm/recoil@0.0.11/umd/recoil.production.js"></script>CDN上のすべてのRecoilファイルは、jsdelivrで参照できます。
ESLint
プロジェクトでeslint-plugin-react-hooksを使用している場合。たとえば、次のようなeslint設定では、
// previous .eslint config { "plugins": [ "react-hooks" ], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } }
additionalHooks
のリストに'useRecoilCallback'を追加することをお勧めします。
この変更により、ESLintはuseRecoilCallback()
に渡された依存関係が誤って指定された場合に警告を出し、修正を提案します。
additionalHooks
のフォーマットは正規表現の文字列です。// modified .eslint config { "plugins": [ "react-hooks" ], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": [ "warn", { "additionalHooks": "useRecoilCallback" } ] } }
参考サイト
・公式ドキュメント
・npm
・yarn
・Webpack
・Rollup
・Babel
・preset@babel/preset-env
・jsdelivr
・eslint-plugin-react-hooks
・useRecoilCallback
・みらい翻訳
全目次
- 投稿日:2020-10-20T01:49:54+09:00
Recoil公式ドキュメント 翻訳②
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
コアコンセプト
概要
Recoilを使用すると、atom(共有state)からselector(純粋関数)を通ってReactコンポーネントに流れるデータフローグラフを作成できます。
atomは、コンポーネントが登録できるstateの単位です。selectorは、このstateを同期的または非同期的に変換します。Atoms
atomはstateの単位です。
atomが更新されると、登録された各コンポーネントが新しい値で再描画されます。実行時にも作成できます。[React local component state] の代わりにatomを使用できます。同じatomが複数のコンポーネントから使用されている場合、それらのコンポーネントはすべてstateを共有します。atomは、atom関数を使用して作成されます。
const fontSizeState = atom({ key: 'fontSizeState', default: 14, });atomには一意のkeyが必要で、これはデバッグ、永続化、およびすべてのatomのマップを表示できる特定の高度なAPIに使用されます。
2つのatomが同じkeyを持つとエラーになるで、それらがグローバルに一意であることを確認してください。コンポーネントのstateと同様に、既定値もあります。コンポーネントからatomを読み書きするには、
useRecoilState
というHookを使用します。ReactのuseState
に似ているが、コンポーネント間でstateを共有できるようになります。function FontButton() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); return ( <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}> Click to Enlarge </button> ); }ボタンをクリックすると、ボタンのフォントサイズが1つ大きくなります。
他のコンポーネントでも同じフォントサイズを使用できるようになりました。function Text() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); return <p style={{fontSize}}>This text will increase in size too.</p>; }Selectors
selectorは、atomやその他のselectorを入力として受け付ける純粋な関数です。
これらの上流のatomまたはselectorが更新されると、selector関数が再評価されます。コンポーネントはatomと同じようにselectorに登録でき、selectorが変更されると再レンダリングされます。selectorは、stateに基づく派生データを計算するために使用されます。これにより冗長なstateを避けることができ、通常はreducerがstateを同期させて有効に保つ必要がなくなります。その代わりに、stateの最小セットはatomに格納され、それ以外はすべて、その最小stateの関数として効率的に計算されます。selectorは、どのコンポーネントが必要とし、どのstateに依存しているかを追跡するので、この機能的なアプローチがより効率的になります。
構成要素の観点から見ると、selectorとatomは同じ境界面を有するため、互いに置換することができます。
selectorは、selector関数を使用して定義します。
const fontSizeLabelState = selector({ key: 'fontSizeLabelState', get: ({get}) => { const fontSize = get(fontSizeState); const unit = 'px'; return `${fontSize}${unit}`; }, });getプロパティは、計算される関数です。渡されたget引数を使用して、atomやその他のselectorの値にアクセスできます。別のatomまたはselectorにアクセスすると、依存関係が作成され、別のatomまたはselectorを更新すると、このatomまたはselectorが再計算されます。
この
fontSizeLabelState
の例では、selectorにはfontSizeState
atomという1つの依存関係があります。
概念的には、fontSizeLabelState
selectorはfontSizeState
を入力として受け取り、フォーマットされたフォントサイズラベルを出力として返す純粋な関数のように動作します。selectorは、
useRecoilValue()
を使用して読み取ることができます。
これは、atomまたはselectorを引数として取り、対応する値を返します。fontSizeLabelState
selectorが書き込み可能ではないため、useRecoilState()
は使用しません。
(書き込み可能selectorの詳細については、selectorAPIリファレンスを参照してください。)function FontButton() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); const fontSizeLabel = useRecoilValue(fontSizeLabelState); return ( <> <div>Current font size: ${fontSizeLabel}</div> <button onClick={() => setFontSize(fontSize + 1)} style={{fontSize}}> Click to Enlarge </button> </> ); }ボタンをクリックすると、ボタンのフォントサイズが大きくなり、現在のフォントサイズを反映するようにフォントサイズのラベルが更新されます。
参考サイト
・公式ドキュメント
・Pure function (純粋関数)とは
・みらい翻訳
全目次
- 投稿日:2020-10-20T01:49:54+09:00
Recoil公式ドキュメント 翻訳② 前書き-コアコンセプト
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
コアコンセプト
概要
Recoilを使用すると、atom(共有state)からselector(純粋関数)を通ってReactコンポーネントに流れるデータフローグラフを作成できます。
atomは、コンポーネントが登録できるstateの単位です。selectorは、このstateを同期的または非同期的に変換します。Atoms
atomはstateの単位です。
atomが更新されると、登録された各コンポーネントが新しい値で再描画されます。実行時にも作成できます。[React local component state] の代わりにatomを使用できます。同じatomが複数のコンポーネントから使用されている場合、それらのコンポーネントはすべてstateを共有します。atomは、atom関数を使用して作成されます。
const fontSizeState = atom({ key: 'fontSizeState', default: 14, });atomには一意のkeyが必要で、これはデバッグ、永続化、およびすべてのatomのマップを表示できる特定の高度なAPIに使用されます。
2つのatomが同じkeyを持つとエラーになるで、それらがグローバルに一意であることを確認してください。コンポーネントのstateと同様に、既定値もあります。コンポーネントからatomを読み書きするには、
useRecoilState
というHookを使用します。ReactのuseState
に似ているが、コンポーネント間でstateを共有できるようになります。function FontButton() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); return ( <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}> Click to Enlarge </button> ); }ボタンをクリックすると、ボタンのフォントサイズが1つ大きくなります。
他のコンポーネントでも同じフォントサイズを使用できるようになりました。function Text() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); return <p style={{fontSize}}>This text will increase in size too.</p>; }Selectors
selectorは、atomやその他のselectorを入力として受け付ける純粋な関数です。
これらの上流のatomまたはselectorが更新されると、selector関数が再評価されます。
コンポーネントはatomと同じようにselectorに登録でき、selectorが変更されると再レンダリングされます。selectorは、stateに基づく派生データを計算するために使用されます。これにより冗長なstateを避けることができ、通常はreducerがstateを同期させて有効に保つ必要がなくなります。その代わりに、stateの最小セットはatomに格納され、それ以外はすべて、その最小stateの関数として効率的に計算されます。selectorは、どのコンポーネントが必要とし、どのstateに依存しているかを追跡するので、この機能的なアプローチがより効率的になります。
構成要素の観点から見ると、selectorとatomは同じ境界面を有するため、互いに置換することができます。
selectorは、selector関数を使用して定義します。
const fontSizeLabelState = selector({ key: 'fontSizeLabelState', get: ({get}) => { const fontSize = get(fontSizeState); const unit = 'px'; return `${fontSize}${unit}`; }, });getプロパティは、計算される関数です。渡されたget引数を使用して、atomやその他のselectorの値にアクセスできます。別のatomまたはselectorにアクセスすると、依存関係が作成され、別のatomまたはselectorを更新すると、このatomまたはselectorが再計算されます。
この
fontSizeLabelState
の例では、selectorにはfontSizeState
atomという1つの依存関係があります。
概念的には、fontSizeLabelState
selectorはfontSizeState
を入力として受け取り、フォーマットされたフォントサイズラベルを出力として返す純粋な関数のように動作します。selectorは、
useRecoilValue()
を使用して読み取ることができます。
これは、atomまたはselectorを引数として取り、対応する値を返します。
fontSizeLabelState
selectorが書き込み可能ではないため、useRecoilState()
は使用しません。
(書き込み可能selectorの詳細については、selectorAPIリファレンスを参照してください。)function FontButton() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); const fontSizeLabel = useRecoilValue(fontSizeLabelState); return ( <> <div>Current font size: ${fontSizeLabel}</div> <button onClick={() => setFontSize(fontSize + 1)} style={{fontSize}}> Click to Enlarge </button> </> ); }ボタンをクリックすると、ボタンのフォントサイズが大きくなり、現在のフォントサイズを反映するようにフォントサイズのラベルが更新されます。
参考サイト
・公式ドキュメント
・Pure function (純粋関数)とは
・みらい翻訳
全目次
- 投稿日:2020-10-20T01:49:54+09:00
Recoil公式ドキュメント 翻訳② コアコンセプト
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
コアコンセプト
概要
Recoilを使用すると、atom(共有state)からselector(純粋関数)を通ってReactコンポーネントに流れるデータフローグラフを作成できます。
atomは、コンポーネントが登録できるstateの単位です。selectorは、このstateを同期的または非同期的に変換します。Atoms
atomはstateの単位です。
atomが更新されると、登録された各コンポーネントが新しい値で再描画されます。実行時にも作成できます。[React local component state] の代わりにatomを使用できます。同じatomが複数のコンポーネントから使用されている場合、それらのコンポーネントはすべてstateを共有します。atomは、atom関数を使用して作成されます。
const fontSizeState = atom({ key: 'fontSizeState', default: 14, });atomには一意のkeyが必要で、これはデバッグ、永続化、およびすべてのatomのマップを表示できる特定の高度なAPIに使用されます。
2つのatomが同じkeyを持つとエラーになるで、それらがグローバルに一意であることを確認してください。コンポーネントのstateと同様に、既定値もあります。コンポーネントからatomを読み書きするには、
useRecoilState
というHookを使用します。ReactのuseState
に似ているが、コンポーネント間でstateを共有できるようになります。function FontButton() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); return ( <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}> Click to Enlarge </button> ); }ボタンをクリックすると、ボタンのフォントサイズが1つ大きくなります。
他のコンポーネントでも同じフォントサイズを使用できるようになりました。function Text() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); return <p style={{fontSize}}>This text will increase in size too.</p>; }Selectors
selectorは、atomやその他のselectorを入力として受け付ける純粋な関数です。
これらの上流のatomまたはselectorが更新されると、selector関数が再評価されます。
コンポーネントはatomと同じようにselectorに登録でき、selectorが変更されると再レンダリングされます。selectorは、stateに基づく派生データを計算するために使用されます。これにより冗長なstateを避けることができ、通常はreducerがstateを同期させて有効に保つ必要がなくなります。その代わりに、stateの最小セットはatomに格納され、それ以外はすべて、その最小stateの関数として効率的に計算されます。selectorは、どのコンポーネントが必要とし、どのstateに依存しているかを追跡するので、この機能的なアプローチがより効率的になります。
構成要素の観点から見ると、selectorとatomは同じ境界面を有するため、互いに置換することができます。
selectorは、selector関数を使用して定義します。
const fontSizeLabelState = selector({ key: 'fontSizeLabelState', get: ({get}) => { const fontSize = get(fontSizeState); const unit = 'px'; return `${fontSize}${unit}`; }, });getプロパティは、計算される関数です。渡されたget引数を使用して、atomやその他のselectorの値にアクセスできます。別のatomまたはselectorにアクセスすると、依存関係が作成され、別のatomまたはselectorを更新すると、このatomまたはselectorが再計算されます。
この
fontSizeLabelState
の例では、selectorにはfontSizeState
atomという1つの依存関係があります。
概念的には、fontSizeLabelState
selectorはfontSizeState
を入力として受け取り、フォーマットされたフォントサイズラベルを出力として返す純粋な関数のように動作します。selectorは、
useRecoilValue()
を使用して読み取ることができます。
これは、atomまたはselectorを引数として取り、対応する値を返します。
fontSizeLabelState
selectorが書き込み可能ではないため、useRecoilState()
は使用しません。
(書き込み可能selectorの詳細については、selectorAPIリファレンスを参照してください。)function FontButton() { const [fontSize, setFontSize] = useRecoilState(fontSizeState); const fontSizeLabel = useRecoilValue(fontSizeLabelState); return ( <> <div>Current font size: ${fontSizeLabel}</div> <button onClick={() => setFontSize(fontSize + 1)} style={{fontSize}}> Click to Enlarge </button> </> ); }ボタンをクリックすると、ボタンのフォントサイズが大きくなり、現在のフォントサイズを反映するようにフォントサイズのラベルが更新されます。
参考サイト
・公式ドキュメント
・Pure function (純粋関数)とは
・みらい翻訳
全目次
- 投稿日:2020-10-20T01:18:52+09:00
Recoil公式ドキュメント 翻訳①
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
- 前書き
- 動機
- コアコンセプト
- インストール
- 入門
- 基本チュートリアル
- ガイド
- APIリファレンス
動機
互換性と単純さの理由から、外部のグローバル状態ではなく、Reactに組み込まれている状態(state)管理機能を使用することをお勧めします。
しかし、Reactにはいくつかの制限があります。
- コンポーネントの状態は、共通の祖先に押し上げることによってのみ共有できますが、これには再レンダリングが必要な巨大なツリーが含まれる場合があります。
- コンテキストは単一の値のみを格納でき、それぞれが独自のコンシューマを持つ値の不確定なセットは格納できません。
- どちらの方法でも、木(ツリー)の上部(stateが存在しなければならない場所)と葉(stateが使用される場所)をコード分割するのは困難です。
APIとセマンティクスと振る舞いの両方を可能な限りReactらしく維持しながら、これを改善したいと考えています。
Recoilは、Reactツリーに直交するだけでなく、固有かつ添付(アタッチ)された有向グラフを定義します。
state変化は、このグラフの根(我々はatomと呼んでいます)から純粋な関数(selectorと呼んでいます)を通ってコンポーネントへと流れます。
この方法では、次のようになります。
- 共有しているstateが、React local state(必要に応じてReducer等でカプセル化することができる)と同じ単純なget/setインターフェースを持つ、定型のないAPIを入手しました。
- Concurrent Modeやその他のReactの新機能が利用可能になれば、それらと互換性を持つ可能性があります。
- state定義は増分及び分散されているため、コード分割が可能です。
- stateは、それを使用するコンポーネントを変更することなく、派生データで置き換えることができます。
- 派生データは、それを使用するコンポーネントを変更することなく、同期と非同期の間で移動できます。
- ナビゲーションは、linkにおけるstate遷移の符号化(エンコーディング)さえも、第一級の概念として扱うことができる。
- 後方互換性のある方法でアプリケーションのstate全体を永続化するのは簡単なので、永続化されたstateはアプリケーションの変更に耐えることができます。
参考サイト
・公式ドキュメント
・フリーソフトによるデータ解析・マイニング 第61回 ←(有向グラフ)
・Pure function (純粋関数)とは
・みらい翻訳
全目次
- 前書き
- 動機
- コアコンセプト
- インストール
- 入門
- 基本チュートリアル
- イントロ
- Atoms
- Selectors
- ガイド
- 非同期データクエリ
- 非同期状態(state)同期
- 状態(state)の永続性
- APIリファレンス
- Core
- 実用(utils)
- 投稿日:2020-10-20T01:18:52+09:00
Recoil公式ドキュメント 翻訳① 動機
Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。
追々追加していきます。(多分)
目次
※全目次は一番下にあります
動機
互換性と単純さの理由から、外部のグローバル状態ではなく、Reactに組み込まれている状態(state)管理機能を使用することをお勧めします。
しかし、Reactにはいくつかの制限があります。
- コンポーネントの状態は、共通の祖先に押し上げることによってのみ共有できますが、これには再レンダリングが必要な巨大なツリーが含まれる場合があります。
- コンテキストは単一の値のみを格納でき、それぞれが独自のコンシューマを持つ値の不確定なセットは格納できません。
- どちらの方法でも、木(ツリー)の上部(stateが存在しなければならない場所)と葉(stateが使用される場所)をコード分割するのは困難です。
APIとセマンティクスと振る舞いの両方を可能な限りReactらしく維持しながら、これを改善したいと考えています。
Recoilは、Reactツリーに直交するだけでなく、固有かつ添付(アタッチ)された有向グラフを定義します。
state変化は、このグラフの根(我々はatomと呼んでいます)から純粋な関数(selectorと呼んでいます)を通ってコンポーネントへと流れます。
この方法では、次のようになります。
- 共有しているstateが、React local state(必要に応じてReducer等でカプセル化することができる)と同じ単純なget/setインターフェースを持つ、定型のないAPIを入手しました。
- Concurrent Modeやその他のReactの新機能が利用可能になれば、それらと互換性を持つ可能性があります。
- state定義は増分及び分散されているため、コード分割が可能です。
- stateは、それを使用するコンポーネントを変更することなく、派生データで置き換えることができます。
- 派生データは、それを使用するコンポーネントを変更することなく、同期と非同期の間で移動できます。
- ナビゲーションは、linkにおけるstate遷移の符号化(エンコーディング)さえも、第一級の概念として扱うことができる。
- 後方互換性のある方法でアプリケーションのstate全体を永続化するのは簡単なので、永続化されたstateはアプリケーションの変更に耐えることができます。
参考サイト
・公式ドキュメント
・フリーソフトによるデータ解析・マイニング 第61回 ←(有向グラフ)
・Pure function (純粋関数)とは
・みらい翻訳
全目次