インストール

モジュールをインストールします

  1. npm install @wordpress/data --save

このパッケージは、あなたのコードがES2015+環境で実行されることを前提としています。もし、言語機能やAPIのサポートが限られているか、全くない環境を使用している場合は、コードに@wordpress/babel-preset-defaultで提供されるポリフィルを含めるべきです

ストアの登録

register関数を使用して、独自のストアを中央データレジストリに追加します。この関数は1つの引数を受け取ります - createReduxStoreファクトリ関数で作成できるストア記述子です。createReduxStoreは2つの引数を受け取ります:モジュールを識別するための名前と、状態がどのように表現され、変更され、アクセスされるかを説明する値を持つ構成オブジェクトです。最低限、状態の形状と、ストアにディスパッチされたアクションに応じてどのように変更されるかを説明するリデューサー関数を提供する必要があります。

  1. import apiFetch from '@wordpress/api-fetch';
  2. import { createReduxStore, register } from '@wordpress/data';
  3. const DEFAULT_STATE = {
  4. prices: {},
  5. discountPercent: 0,
  6. };
  7. const actions = {
  8. setPrice( item, price ) {
  9. return {
  10. type: 'SET_PRICE',
  11. item,
  12. price,
  13. };
  14. },
  15. startSale( discountPercent ) {
  16. return {
  17. type: 'START_SALE',
  18. discountPercent,
  19. };
  20. },
  21. fetchFromAPI( path ) {
  22. return {
  23. type: 'FETCH_FROM_API',
  24. path,
  25. };
  26. },
  27. };
  28. const store = createReduxStore( 'my-shop', {
  29. reducer( state = DEFAULT_STATE, action ) {
  30. switch ( action.type ) {
  31. case 'SET_PRICE':
  32. return {
  33. ...state,
  34. prices: {
  35. ...state.prices,
  36. [ action.item ]: action.price,
  37. },
  38. };
  39. case 'START_SALE':
  40. return {
  41. ...state,
  42. discountPercent: action.discountPercent,
  43. };
  44. }
  45. return state;
  46. },
  47. actions,
  48. selectors: {
  49. getPrice( state, item ) {
  50. const { prices, discountPercent } = state;
  51. const price = prices[ item ];
  52. return price * ( 1 - 0.01 * discountPercent );
  53. },
  54. },
  55. controls: {
  56. FETCH_FROM_API( action ) {
  57. return apiFetch( { path: action.path } );
  58. },
  59. },
  60. resolvers: {
  61. *getPrice( item ) {
  62. const path = '/wp/v2/prices/' + item;
  63. const price = yield actions.fetchFromAPI( path );
  64. return actions.setPrice( item, price );
  65. },
  66. },
  67. } );
  68. register( store );
  1. - `````name````` (`````string`````) ストアの名前
  2. - `````instantiate````` (`````Function`````) 次のメソッドを持つ[Reduxライクなストアオブジェクト](https://redux.js.org/basics/store)を返します:
  3. - `````getState()`````: 登録されたリデューサーの状態値を返します
  4. - Reduxの並行: [`````getState`````](https://redux.js.org/api/store#getstate)
  5. - `````subscribe( listener: Function )`````: 状態の値が変更されるたびに呼び出される関数を登録します。
  6. - Reduxの並行: [`````subscribe`````](https://redux.js.org/api/store#subscribelistener)
  7. - `````dispatch( action: Object )`````: アクションオブジェクトを与えられた場合、登録されたリデューサーを呼び出し、状態値を更新します。
  8. - Reduxの並行: [`````dispatch`````](https://redux.js.org/api/store#dispatchaction)
  9. <a name="redux-store-options"></a>
  10. ### Reduxストアオプション
  11. #### リデューサー
  12. [**リデューサー**](https://redux.js.org/basics/reducers)は、前の`````state`````と`````action`````を引数として受け取り、更新された`````state`````値を返す関数です。
  13. #### アクション
  14. **`````actions`````**オブジェクトは、ストアで利用可能なすべての[action creators](https://redux.js.org/glossary#action-creator)を説明する必要があります。アクションクリエイターは、オプションで引数を受け取り、登録されたリデューサーにディスパッチするアクションオブジェクトを返す関数です。*アクションをディスパッチすることは、状態を変更するための主要なメカニズムです。*
  15. #### セレクター
  16. **`````selectors`````**オブジェクトには、状態値にアクセスし、導出するための関数のセットが含まれています。セレクターは、状態とオプションの引数を受け取り、状態からいくつかの値を返す関数です。*セレクターを呼び出すことは、状態からデータを取得するための主要なメカニズムです*、そして通常は変更に対してより敏感で、[正規化されたオブジェクト](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape#designing-a-normalized-state)としてはあまり使いやすくない生データの上に有用な抽象化を提供します。
  17. #### リゾルバー
  18. **リゾルバー**は、セレクターの副作用です。セレクターの結果が外部ソースから満たされる必要がある場合、最初にセレクターが呼び出されたときに満たす動作が行われるようにリゾルバーを定義できます。
  19. `````resolvers`````オプションは、各キーが作用するセレクターの名前であり、値がセレクターに渡されるのと同じ引数を受け取る関数であるオブジェクトとして渡す必要があります。これにより、必要に応じてセレクターの要件を満たすためにディスパッチできます。ほとんどのデータ消費者がその後の状態変更にサブスクライブすることを考慮に入れています(`````subscribe`````または`````withSelect`````)。
  20. #### コントロール
  21. **コントロール**は、特定のアクションタイプに関連付けられた実行フローベヘイビアを定義します。これは、ストアの非同期データフローを実装する際に特に便利です。特定の制御されたアクションタイプを生成するジェネレーターとしてアクションクリエイターやリゾルバーを定義することにより、実行はコントロールハンドラーによって定義された通りに進行します。
  22. `````controls`````オプションは、各キーが作用するアクションタイプの名前であり、値が元のアクションオブジェクトを受け取る関数であるオブジェクトとして渡す必要があります。これは、評価が続行されるべき時に解決される約束を返すか、値を返す必要があります。値または解決された約束の値は、yield割り当ての戻り値に割り当てられます。コントロールハンドラーがundefinedを返す場合、実行は続行されません。
  23. 詳細については、[`````@wordpress/redux-routine`````のドキュメント](https://github.com/WordPress/gutenberg/tree/HEAD/packages/redux-routine/README.md)を参照してください。
  24. #### 初期状態
  25. ストアのためのオプションのプリロードされた初期状態です。これを使用して、いくつかのシリアライズされた状態値やサーバーサイドで生成された状態を復元できます。
  26. <a name="generic-stores"></a>
  27. ## 一般的なストア
  28. `````@wordpress/data`````モジュールは、他のデータシステムとの統合や、データシステムに対するより直接的な制御が必要な状況のために、より高度で一般的なインターフェースを提供します。この場合、データストアは`````@wordpress/data`````の外部で実装され、その後3つの関数を介して接続される必要があります:
  29. - `````getSelectors()`````: ストアに事前にマッピングされたセレクター関数のオブジェクトを返します。
  30. - `````getActions()`````: ストアに事前にマッピングされたアクション関数のオブジェクトを返します。
  31. - `````subscribe( listener: Function )`````: 状態の値が変更されるたびに呼び出される関数を登録します。
  32. - 次の違いを持つRedux[`````subscribe`````](https://redux.js.org/api/store#subscribelistener)として動作します:
  33. - アンソ subscribeを実装する必要はありません。レジストリはそれを使用しないためです。
  34. - 1つのリスナー(レジストリ)のみをサポートする必要があります。
  35. カスタムストアのために上記のインターフェースを実装することにより、レジストリと`````withSelect`````および`````withDispatch`````の高階コンポーネントをアプリケーションコードで使用する利点を得ることができます。これにより、既存のデータシステムや代替データシステムとのシームレスな統合が提供されます。
  36. 既存のreduxストアを独自のリデューサー、ストアエンハンサー、ミドルウェアと統合することは、次のように実行できます:
  37. *例:*
  38. ``````bash
  39. import { register } from '@wordpress/data';
  40. import existingSelectors from './existing-app/selectors';
  41. import existingActions from './existing-app/actions';
  42. import createStore from './existing-app/store';
  43. const reduxStore = createStore();
  44. const mapValues = ( obj, callback ) =>
  45. Object.entries( obj ).reduce(
  46. ( acc, [ key, value ] ) => ( {
  47. ...acc,
  48. [ key ]: callback( value ),
  49. } ),
  50. {}
  51. );
  52. const boundSelectors = mapValues(
  53. existingSelectors,
  54. ( selector ) =>
  55. ( ...args ) =>
  56. selector( reduxStore.getState(), ...args )
  57. );
  58. const boundActions = mapValues(
  59. existingActions,
  60. ( action ) =>
  61. ( ...args ) =>
  62. reduxStore.dispatch( action( ...args ) )
  63. );
  64. const genericStore = {
  65. name: 'existing-app',
  66. instantiate: () => ( {
  67. getSelectors: () => boundSelectors,
  68. getActions: () => boundActions,
  69. subscribe: reduxStore.subscribe,
  70. } ),
  71. };
  72. register( genericStore );
  73. `

完全にカスタムストアをゼロから実装することも可能です:

例:

  1. import { register } from '@wordpress/data';
  2. function customStore() {
  3. return {
  4. name: 'custom-data',
  5. instantiate: () => {
  6. const listeners = new Set();
  7. const prices = { hammer: 7.5 };
  8. function storeChanged() {
  9. for ( const listener of listeners ) {
  10. listener();
  11. }
  12. }
  13. function subscribe( listener ) {
  14. listeners.add( listener );
  15. return () => listeners.delete( listener );
  16. }
  17. const selectors = {
  18. getPrice( itemName ) {
  19. return prices[ itemName ];
  20. },
  21. };
  22. const actions = {
  23. setPrice( itemName, price ) {
  24. prices[ itemName ] = price;
  25. storeChanged();
  26. },
  27. };
  28. return {
  29. getSelectors: () => selectors,
  30. getActions: () => actions,
  31. subscribe,
  32. };
  33. },
  34. };
  35. }
  36. register( customStore );

Reduxとの比較

データモジュールは、Reduxコア原則APIメソッド名の多くを共有しています。実際、Reduxの上に実装されています。異なる点は、別々だが相互依存するストアを作成するためのモジュール化パターンを確立し、データアクセスの主要なエントリポイントとしてセレクター関数などの慣習を体系化することです。

この区別を補完するために高階コンポーネントが作成されました。withSelectwithDispatchを分割する意図は、React Reduxではconnectの下でmapStateToPropsおよびmapDispatchToProps引数として結合されているため、ディスパッチが状態変更へのサブスクリプションに依存しないことをより正確に反映し、状態から派生した値をwithDispatchで使用できるようにすることです(高階コンポーネントの合成を介して)。

データモジュールには、リゾルバーコントロールを通じて非同期副作用を処理するための組み込みソリューションもあります。これらは、https://redux.js.org/advanced/async-actionsのような標準redux非同期ソリューションとは若干異なります。

ReduxおよびReact Reduxとの具体的な実装の違い:

  • Reduxでは、subscribeリスナーは、状態の値が変更されたかどうかに関係なく、すべてのディスパッチで呼び出されます。
    • @wordpress/dataでは、サブスクライバーは状態が変更されたときのみ呼び出されます。
  • React Reduxでは、mapStateToProps関数はオブジェクトを返す必要があります。
    • @wordpress/dataでは、withSelectマッピング関数は、注入するプロパティがない場合、undefinedを返すことができます。
  • React Reduxでは、mapDispatchToProps引数はオブジェクトまたは関数として定義できます。
    • @wordpress/dataでは、withDispatch高階コンポーネントクリエイターには関数を渡す必要があります。

API

AsyncModeProvider

データモジュールコンポーネントの再レンダリングを同期モードと非同期モードの間で切り替えるために使用されるコンテキストプロバイダーコンポーネント。

使用法

  1. import { useSelect, AsyncModeProvider } from '@wordpress/data';
  2. import { store as blockEditorStore } from '@wordpress/block-editor';
  3. function BlockCount() {
  4. const count = useSelect( ( select ) => {
  5. return select( blockEditorStore ).getBlockCount();
  6. }, [] );
  7. return count;
  8. }
  9. function App() {
  10. return (
  11. <AsyncModeProvider value={ true }>
  12. <BlockCount />
  13. </AsyncModeProvider>
  14. );
  15. }

この例では、BlockCountコンポーネントが非同期に再レンダリングされます。

つまり、より重要なタスクが実行されている場合(入力にタイプするなど)、

再レンダリングはブラウザがアイドルになるまで遅延されます。

複数のレベルのAsyncModeProviderをネストして、レンダリング動作を微調整することが可能です。

パラメータ

  • props.value boolean: 非同期モードを有効にします。

戻り値

  • Component: レンダリングされるコンポーネントです。

combineReducers

combineReducersヘルパー関数は、値が異なるリデューシング関数のオブジェクトを、registerReducerに渡すことができる単一のリデューシング関数に変換します。

使用法

  1. import { combineReducers, createReduxStore, register } from '@wordpress/data';
  2. const prices = ( state = {}, action ) => {
  3. return action.type === 'SET_PRICE'
  4. ? {
  5. ...state,
  6. [ action.item ]: action.price,
  7. }
  8. : state;
  9. };
  10. const discountPercent = ( state = 0, action ) => {
  11. return action.type === 'START_SALE' ? action.discountPercent : state;
  12. };
  13. const store = createReduxStore( 'my-shop', {
  14. reducer: combineReducers( {
  15. prices,
  16. discountPercent,
  17. } ),
  18. } );
  19. register( store );

タイプ

  • import('./types').combineReducers

パラメータ

  • reducers Object: 結合する必要がある異なるリデューシング関数に対応する値を持つオブジェクトです。

戻り値

  • Function: reducersオブジェクト内のすべてのリデューサーを呼び出し、同じ形状の状態オブジェクトを構築するリデューサーです。

コントロール

未文書化の宣言。

createReduxStore

リデューサー、アクション、セレクター、コントロール、リゾルバーを説明するプロパティを含む、提供されたReduxストア構成のためのデータストア記述子を作成します。

使用法

  1. import { createReduxStore } from '@wordpress/data';
  2. const store = createReduxStore( 'demo', {
  3. reducer: ( state = 'OK' ) => state,
  4. selectors: {
  5. getValue: ( state ) => state,
  6. },
  7. } );

パラメータ

  • key string: ユニークな名前空間識別子。
  • options ReduxStoreConfig<State,Actions,Selectors>: リデューサー、アクション、セレクター、リゾルバーを説明するプロパティを持つ登録されたストアオプションです。

戻り値

  • StoreDescriptor<ReduxStoreConfig<State,Actions,Selectors>>: ストアオブジェクトです。

createRegistry

オプションの初期ストア構成オブジェクトを与えられた新しいストアレジストリを作成します。

パラメータ

  • storeConfigs Object: 初期ストア構成。
  • parent Object?: 親レジストリ。

戻り値

  • WPDataRegistry: データレジストリです。

createRegistryControl

追加のカリー引数をregistryオブジェクトで受け取るコントロール関数を作成します。通常のコントロールは署名を持ちます

  1. ( action ) => iteratorOrPromise;

コントロールがバインドされているactionで動作するのに対し、レジストリコントロールは署名を持ちます:

  1. ( registry ) => ( action ) => iteratorOrPromise;

レジストリコントロールは通常、データを選択したり、登録されたストアにアクションをディスパッチするために使用されます。

  1. *パラメータ*
  2. - registryControl `````Function`````: レジストリオブジェクトを受け取り、コントロールを返す関数です。
  3. *戻り値*
  4. - `````Function`````: ストアに登録できるレジストリコントロールです。
  5. <a name="createregistryselector"></a>
  6. ### createRegistrySelector
  7. レジストリ`````select`````関数で追加のカリー引数を受け取るセレクター関数を作成します。通常のセレクターは署名を持ちます
  8. ``````bash
  9. ( state, ...selectorArgs ) => result;
  10. `

ストアのstateからデータを選択することを可能にしますが、レジストリセレクターは署名を持ちます:

  1. ( select ) =>
  2. ( state, ...selectorArgs ) =>
  3. result;

他の登録されたストアからも選択をサポートします。

使用法

  1. import { store as coreStore } from '@wordpress/core-data';
  2. import { store as editorStore } from '@wordpress/editor';
  3. const getCurrentPostId = createRegistrySelector( ( select ) => ( state ) => {
  4. return select( editorStore ).getCurrentPostId();
  5. } );
  6. const getPostEdits = createRegistrySelector( ( select ) => ( state ) => {
  7. // calling another registry selector just like any other function
  8. const postType = getCurrentPostType( state );
  9. const postId = getCurrentPostId( state );
  10. return select( coreStore ).getEntityRecordEdits(
  11. 'postType',
  12. postType,
  13. postId
  14. );
  15. } );
  1. (通常の非レジストリセレクター内でも機能します)そして、
  2. レジストリを引数として渡す必要はありません。セレクターをストアに登録するときにレジストリバインディングが自動的に行われます。
  3. *パラメータ*
  4. - registrySelector `````Function`````: レジストリ`````select`````関数を受け取り、状態セレクターを返す関数です。
  5. *戻り値*
  6. - `````Function`````: ストアに登録できるレジストリセレクターです。
  7. <a name="createselector"></a>
  8. ### createSelector
  9. 依存関係の配列とセレクターのパラメータに従って計算された値をキャッシュするメモ化されたセレクターを作成し、いずれかが変更されたときのみ値を再計算します。
  10. *関連*
  11. - `````rememo`````パッケージのドキュメント、`````createSelector`````関数が再エクスポートされています。
  12. *パラメータ*
  13. - selector `````Function`````: 状態とパラメータから値を計算するセレクター関数です。
  14. - getDependants `````Function`````: “依存”オブジェクトの配列を返す関数です。
  15. *戻り値*
  16. - `````Function`````: 計算された戻り値をキャッシュする`````selector`````のメモ化バージョンです。
  17. <a name="dispatch"></a>
  18. ### dispatch
  19. ストア記述子が与えられた場合、ストアのアクションクリエイターのオブジェクトを返します。アクションクリエイターを呼び出すと、それがディスパッチされ、状態値がそれに応じて更新されます。
  20. 注意:ディスパッチによって返されたアクションクリエイターは、呼び出されると約束を返します。
  21. *使用法*
  22. ``````bash
  23. import { dispatch } from '@wordpress/data';
  24. import { store as myCustomStore } from 'my-custom-store';
  25. dispatch( myCustomStore ).setPrice( 'hammer', 9.75 );
  26. `

パラメータ

  • storeNameOrDescriptor StoreNameOrDescriptor: ストア記述子。ストア名を渡すレガシー呼び出し規約もサポートされています。

戻り値

  • DispatchReturn< StoreNameOrDescriptor >: アクションクリエイターを含むオブジェクトです。

プラグイン

レジストリで使用できるプラグインのオブジェクトです。

関連

タイプ

  • Object

register

標準の@wordpress/dataストア記述子を登録します。

使用法

  1. import { createReduxStore, register } from '@wordpress/data';
  2. const store = createReduxStore( 'demo', {
  3. reducer: ( state = 'OK' ) => state,
  4. selectors: {
  5. getValue: ( state ) => state,
  6. },
  7. } );
  8. register( store );

パラメータ

  • store StoreDescriptor: ストア記述子です。

registerGenericStore

非推奨 register( storeDescriptor )を使用してください。
一般的なストアインスタンスを登録します。

パラメータ

  • name string: ストアレジストリ名。
  • store Object: ストアインスタンス({ getSelectors, getActions, subscribe })。

registerStore

非推奨 registerを使用してください。
標準の@wordpress/dataストアを登録します。

パラメータ

  • storeName string: ストアのユニークな名前空間識別子。
  • options Object: ストアの説明(リデューサー、アクション、セレクター、リゾルバー)。

戻り値

  • Object: 登録されたストアオブジェクトです。

RegistryConsumer

提供されたregistryを子コンポーネントに公開するカスタムReactコンテキストコンシューマです。RegistryProviderと一緒に使用されます。

ReactコンテキストAPIについての詳細は、こちらを参照してください:https://react.dev/learn/passing-data-deeply-with-context#step-3-provide-the-context

使用法

  1. import {
  2. RegistryProvider,
  3. RegistryConsumer,
  4. createRegistry
  5. } from '@wordpress/data';
  6. const registry = createRegistry( {} );
  7. const App = ( { props } ) => {
  8. return <RegistryProvider value={ registry }>
  9. <div>Hello There</div>
  10. <RegistryConsumer>
  11. { ( registry ) => (
  12. <ComponentUsingRegistry
  13. { ...props }
  14. registry={ registry }
  15. ) }
  16. </RegistryConsumer>
  17. </RegistryProvider>
  18. }

RegistryProvider

提供されたregistryを子コンポーネントに公開するカスタムコンテキストプロバイダーです。

例については、
RegistryConsumerのドキュメントを参照してください。

resolveSelect

ストア記述子が与えられた場合、ストアのセレクターを状態に事前にバインドしたオブジェクトを返します。これにより、追加の引数を供給するだけで済み、リゾルバーが実行された後に最終的な値に解決される約束を返すように修正されます。

使用法

  1. import { resolveSelect } from '@wordpress/data';
  2. import { store as myCustomStore } from 'my-custom-store';
  3. resolveSelect( myCustomStore ).getPrice( 'hammer' ).then( console.log );

パラメータ

  • storeNameOrDescriptor StoreDescriptor|string: ストア記述子。ストア名を渡すレガシー呼び出し規約もサポートされています。

戻り値

  • Object: ストアの約束でラップされたセレクターを含むオブジェクトです。

select

ストア記述子が与えられた場合、ストアのセレクターのオブジェクトを返します。セレクター関数は、現在の状態を自動的に渡すように事前にバインドされています。消費者として、適用可能な場合はセレクターの引数のみを渡す必要があります。

使用法

  1. import { select } from '@wordpress/data';
  2. import { store as myCustomStore } from 'my-custom-store';
  3. select( myCustomStore ).getPrice( 'hammer' );

パラメータ

  • storeNameOrDescriptor string | T: ストア記述子。ストア名を渡すレガシー呼び出し規約もサポートされています。

戻り値

  • CurriedSelectorsOf< T >: ストアのセレクターを含むオブジェクトです。

subscribe

リスナー関数が与えられた場合、登録されたストアの1つの状態値が変更されるたびにその関数が呼び出されます。オプションのstoreNameOrDescriptorパラメータを指定すると、リスナー関数はその特定の登録ストアの更新時にのみ呼び出されます。

この関数は、サブスクリプションを停止するために使用されるunsubscribe関数を返します。

使用法

  1. import { subscribe } from '@wordpress/data';
  2. const unsubscribe = subscribe( () => {
  3. // You could use this opportunity to test whether the derived result of a
  4. // selector has subsequently changed as the result of a state update.
  5. } );
  6. // Later, if necessary...
  7. unsubscribe();

パラメータ

  • listener Function: コールバック関数です。
  • storeNameOrDescriptor string|StoreDescriptor?: オプションのストア名です。

suspendSelect

ストア記述子が与えられた場合、ストアのセレクターを状態に事前にバインドしたオブジェクトを返します。これにより、追加の引数を供給するだけで済み、セレクターがまだ解決されていない場合に約束をスローするように修正されます。

パラメータ

  • storeNameOrDescriptor StoreDescriptor|string: ストア記述子。ストア名を渡すレガシー呼び出し規約もサポートされています。

戻り値

  • Object: ストアのサスペンスでラップされたセレクターを含むオブジェクトです。

use

レジストリを拡張して、指定されたプラグインによって提供される機能を継承します。プラグインは、レジストリのプロパティに一致するプロパティを持つオブジェクトで、デフォルトのレジストリ動作を拡張するためにマージされます。

パラメータ

  • plugin Object: プラグインオブジェクトです。

useDispatch

現在のレジストリディスパッチアクションクリエイターを返すカスタムReactフックです。

注意:このフックを使用するコンポーネントは、RegistryProviderのコンテキスト内に存在する必要があります。

使用法

これは、サーバーから動的データを取得する必要があるパターンを示しています

  1. ``````bash
  2. import { useCallback } from 'react';
  3. import { useDispatch, useSelect } from '@wordpress/data';
  4. import { store as myCustomStore } from 'my-custom-store';
  5. function Button( { onClick, children } ) {
  6. return (
  7. <button type="button" onClick={ onClick }>
  8. { children }
  9. </button>
  10. );
  11. }
  12. const SaleButton = ( { children } ) => {
  13. const { stockNumber } = useSelect(
  14. ( select ) => select( myCustomStore ).getStockNumber(),
  15. []
  16. );
  17. const { startSale } = useDispatch( myCustomStore );
  18. const onClick = useCallback( () => {
  19. const discountPercent = stockNumber > 50 ? 10 : 20;
  20. startSale( discountPercent );
  21. }, [ stockNumber ] );
  22. return <Button onClick={ onClick }>{ children }</Button>;
  23. };
  24. // Rendered somewhere in the application:
  25. //
  26. // <SaleButton>Start Sale!</SaleButton>
  27. `

パラメータ

  • storeNameOrDescriptor [StoreNameOrDescriptor]: アクションクリエイターを取得するためのストア名またはその記述子をオプションで提供します。提供されない場合、registry.dispatch関数が代わりに返されます。

戻り値

  • UseDispatchReturn<StoreNameOrDescriptor>: カスタムReactフックです。

useRegistry

レジストリコンテキストを使用するために公開するカスタムReactフックです。

これは、Registry Providerを介して提供されたregistry値を、このフックを実装するコンポーネントに公開します。

useContext Reactフックと同様に動作します。

注意:一般的に、useRegistryは実装に必要ない低レベルのフックです。@wordpress/data APIとのほとんどの相互作用は、useSelectフック、またはwithSelectおよびwithDispatchの高階コンポーネントを介して実行できます。

使用法

  1. import { RegistryProvider, createRegistry, useRegistry } from '@wordpress/data';
  2. const registry = createRegistry( {} );
  3. const SomeChildUsingRegistry = ( props ) => {
  4. const registry = useRegistry();
  5. // ...logic implementing the registry in other react hooks.
  6. };
  7. const ParentProvidingRegistry = ( props ) => {
  8. return (
  9. <RegistryProvider value={ registry }>
  10. <SomeChildUsingRegistry { ...props } />
  11. </RegistryProvider>
  12. );
  13. };

戻り値

  • Function: レジストリコンテキスト値を公開するカスタムReactフックです。

useSelect

登録されたセレクターからプロパティを取得するためのカスタムReactフックです。

一般的に、このカスタムReactフックはフックのルールに従います。

使用法

  1. import { useSelect } from '@wordpress/data';
  2. import { store as myCustomStore } from 'my-custom-store';
  3. function HammerPriceDisplay( { currency } ) {
  4. const price = useSelect(
  5. ( select ) => {
  6. return select( myCustomStore ).getPrice( 'hammer', currency );
  7. },
  8. [ currency ]
  9. );
  10. return new Intl.NumberFormat( 'en-US', {
  11. style: 'currency',
  12. currency,
  13. } ).format( price );
  14. }
  15. // Rendered in the application:
  16. // <HammerPriceDisplay currency="USD" />

上記の例では、HammerPriceDisplayがアプリケーションにレンダリングされると、価格はmapSelectコールバックを使用してストア状態から取得されます。通貨プロパティが変更されると、

その通貨の状態内の価格が取得されます。通貨プロパティが変更されず、他のプロパティが変更される場合、依存関係が通貨だけであるため、価格は変更されません。

データがイベントコールバック内でのみ使用される場合、データはレンダリング時に取得されるべきではないため、セレクター関数を取得する方が便利です。

レンダリング時にセレクターを呼び出す際にuseSelectをこのように使用しないでください

データ変更時にコンポーネントが再レンダリングされないためです。

  1. import { useSelect } from '@wordpress/data';
  2. import { store as myCustomStore } from 'my-custom-store';
  3. function Paste( { children } ) {
  4. const { getSettings } = useSelect( myCustomStore );
  5. function onPaste() {
  6. // Do something with the settings.
  7. const settings = getSettings();
  8. }
  9. return <div onPaste={ onPaste }>{ children }</div>;
  10. }

パラメータ

  • mapSelect T: 状態変更ごとに呼び出される関数。返された値は、このフックを実装するコンポーネントに公開されます。関数は、最初の引数にregistry.selectメソッドを、2番目の引数にregistryを受け取ります。ストアキーが渡されると、ストアのすべてのセレクターが返されます。これは、要素ツリーを作成するために必要なデータではなく、イベントコールバック内でこれらのセレクターを使用するためのものです。
  • deps unknown[]: 提供される場合、これはmapSelectをメモ化し、依存関係が変更されない限り、同じmapSelectが状態変更ごとに呼び出されます。

戻り値

  • UseSelectReturn<T>: カスタムReactフックです。

useSuspenseSelect

  1. *パラメータ*
  2. - mapSelect `````T`````: 状態変更ごとに呼び出される関数。返された値は、このフックを使用するコンポーネントに公開されます。関数は、最初の引数に`````registry.suspendSelect`````メソッドを、2番目の引数に`````registry`````を受け取ります。
  3. - deps `````Array`````: 依存関係配列で、`````mapSelect`````をメモ化するために使用され、依存関係が変更されない限り、同じ`````mapSelect`````が状態変更ごとに呼び出されます。
  4. *戻り値*
  5. - `````ReturnType<T>`````: `````mapSelect`````関数によって返されるデータオブジェクトです。
  6. <a name="withdispatch"></a>
  7. ### withDispatch
  8. 登録されたアクションクリエイターを使用してディスパッチプロパティを追加するために使用される高階コンポーネントです。
  9. *使用法*
  10. ``````bash
  11. function Button( { onClick, children } ) {
  12. return (
  13. <button type="button" onClick={ onClick }>
  14. { children }
  15. </button>
  16. );
  17. }
  18. import { withDispatch } from '@wordpress/data';
  19. import { store as myCustomStore } from 'my-custom-store';
  20. const SaleButton = withDispatch( ( dispatch, ownProps ) => {
  21. const { startSale } = dispatch( myCustomStore );
  22. const { discountPercent } = ownProps;
  23. return {
  24. onClick() {
  25. startSale( discountPercent );
  26. },
  27. };
  28. } )( Button );
  29. // Rendered in the application:
  30. //
  31. // <SaleButton discountPercent="20">Start Sale!</SaleButton>
  32. `

ほとんどのケースでは、mapDispatchToPropsに渡される最初の2つのパラメータを使用するだけで十分です。

ただし、registryオブジェクトを使用してコンポーネントのパフォーマンスを最適化するための非常に高度な使用例があるかもしれません。select関数をレジストリから使用することは、イベントが発生したときにストアから動的データを取得する必要がある場合に便利ですが、同時にそれを使用してコンポーネントをレンダリングすることはありません。このようなシナリオでは、withSelect高階コンポーネントを使用してそのプロパティを計算することを避けることができ、頻繁な値の変更によって引き起こされる不必要な再レンダリングを回避できます。

  1. ``````bash
  2. function Button( { onClick, children } ) {
  3. return (
  4. <button type="button" onClick={ onClick }>
  5. { children }
  6. </button>
  7. );
  8. }
  9. import { withDispatch } from '@wordpress/data';
  10. import { store as myCustomStore } from 'my-custom-store';
  11. const SaleButton = withDispatch( ( dispatch, ownProps, { select } ) => {
  12. // Stock number changes frequently.
  13. const { getStockNumber } = select( myCustomStore );
  14. const { startSale } = dispatch( myCustomStore );
  15. return {
  16. onClick() {
  17. const discountPercent = getStockNumber() > 50 ? 10 : 20;
  18. startSale( discountPercent );
  19. },
  20. };
  21. } )( Button );
  22. // Rendered in the application:
  23. //
  24. // <SaleButton>Start Sale!</SaleButton>
  25. `

注意: mapDispatchToProps関数が常に同じキーを持つオブジェクトを返すことが重要です。たとえば、異なる値が返される条件を含めるべきではありません。

パラメータ

  • mapDispatchToProps Function: プロパティ名のオブジェクトを返す関数で、値はディスパッチバウンドアクションクリエイターであるか、コンポーネントのプロパティを使用して呼び出され、アクションクリエイターを返す関数です。

戻り値

  • ComponentType: マージされたディスパッチャープロパティを持つ強化されたコンポーネントです。

withRegistry

現在のレジストリコンテキストをregistryプロパティとして渡して元のコンポーネントをレンダリングする高階コンポーネントです。

パラメータ

  • OriginalComponent Component: 元のコンポーネントです。

戻り値

  • Component: 強化されたコンポーネントです。

withSelect

登録されたセレクターを使用して状態派生プロパティを注入するために使用される高階コンポーネントです。

使用法

  1. import { withSelect } from '@wordpress/data';
  2. import { store as myCustomStore } from 'my-custom-store';
  3. function PriceDisplay( { price, currency } ) {
  4. return new Intl.NumberFormat( 'en-US', {
  5. style: 'currency',
  6. currency,
  7. } ).format( price );
  8. }
  9. const HammerPriceDisplay = withSelect( ( select, ownProps ) => {
  10. const { getPrice } = select( myCustomStore );
  11. const { currency } = ownProps;
  12. return {
  13. price: getPrice( 'hammer', currency ),
  14. };
  15. } )( PriceDisplay );
  16. // Rendered in the application:
  17. //
  18. // <HammerPriceDisplay currency="USD" />

上記の例では、HammerPriceDisplayがアプリケーションにレンダリングされると、価格は基盤となるPriceDisplayコンポーネントに渡され、ハンマーの価格がストアで変更されると自動的に更新されます。

パラメータ

  • mapSelectToProps Function: 状態変更ごとに呼び出される関数で、コンポーネントのプロパティとマージするプロパティのオブジェクトを返すことが期待されます。

戻り値

  • ComponentType: マージされた状態データプロパティを持つ強化されたコンポーネントです。

batch

  1. - セレクターは更新された状態で呼び出されます。
  2. - セレクターが前の値(厳密な等価性)と異なる値を返す場合、コンポーネントは再レンダリングされます。
  3. アプリケーションが成長するにつれて、これはコストがかかる可能性があるため、可能な限りこれらの両方を実行しないようにすることが重要です。これらの状況の1つは、相互作用が状態を適切に更新するために複数の連続した`````dispatch`````呼び出しを必要とする場合に発生します。`````dispatch`````を呼び出すたびにコンポーネントを再レンダリングしないようにするために、連続したディスパッチ呼び出しを`````batch`````でラップすることができ、これによりコンポーネントは選択子を呼び出し、シーケンスの最後に1回だけ再レンダリングされます。
  4. *使用法*
  5. ``````bash
  6. import { useRegistry } from '@wordpress/data';
  7. function Component() {
  8. const registry = useRegistry();
  9. function callback() {
  10. // This will only rerender the components once.
  11. registry.batch( () => {
  12. registry.dispatch( someStore ).someAction();
  13. registry.dispatch( someStore ).someOtherAction();
  14. } );
  15. }
  16. return <button onClick={ callback }>Click me</button>;
  17. }
  18. `

セレクター

wp.data.select( 'core' )によって返されるオブジェクトで利用可能な次のセレクターです。

  1. import { store as coreDataStore } from '@wordpress/core-data';
  2. import { useSelect } from '@wordpress/data';
  3. function Component() {
  4. const result = useSelect( ( select ) => {
  5. const query = { per_page: 20 };
  6. const selectorArgs = [ 'postType', 'page', query ];
  7. return {
  8. pages: select( coreDataStore ).getEntityRecords( ...selectorArgs ),
  9. hasStartedResolution: select( coreDataStore ).hasStartedResolution(
  10. 'getEntityRecords', // _selectorName_
  11. selectorArgs
  12. ),
  13. hasFinishedResolution: select(
  14. coreDataStore
  15. ).hasFinishedResolution( 'getEntityRecords', selectorArgs ),
  16. isResolving: select( coreDataStore ).isResolving(
  17. 'getEntityRecords',
  18. selectorArgs
  19. ),
  20. };
  21. } );
  22. if ( result.hasStartedResolution ) {
  23. return <>Fetching data...</>;
  24. }
  25. if ( result.isResolving ) {
  26. return (
  27. <>
  28. {
  29. // show a spinner
  30. }
  31. </>
  32. );
  33. }
  34. if ( result.hasFinishedResolution ) {
  35. return (
  36. <>
  37. {
  38. // data is ready
  39. }
  40. </>
  41. );
  42. }
  43. }

hasFinishedResolution

指定されたセレクター名と引数セットの解決が完了した場合はtrueを返します。

パラメータ

  • state State: データ状態です。
  • selectorName string: セレクター名です。
  • args unknown[]?: セレクターに渡される引数です。

戻り値

  • boolean: 解決が完了したかどうかです。

hasStartedResolution

指定されたセレクター名と引数セットの解決がすでにトリガーされている場合はtrueを返します。

パラメータ

  • state State: データ状態です。
  • selectorName string: セレクター名です。
  • args unknown[]?: セレクターに渡される引数です。

戻り値

  • boolean: 解決がトリガーされたかどうかです。

isResolving

指定されたセレクター名と引数セットの解決がトリガーされているが、まだ完了していない場合はtrueを返します。

パラメータ

  • state State: データ状態です。
  • selectorName string: セレクター名です。
  • args unknown[]?: セレクターに渡される引数です。

戻り値

  • boolean: 解決が進行中かどうかです。

セレクタ引数の正規化

特定の状況では、セレクタ/リゾルバのペアリングの特定の 呼び出し に渡される引数を正規化する必要がある場合があります。

各リゾルバは、内部状態にキャッシュされた解決ステータスを持ち、キーは 呼び出し 時にセレクタに供給された引数です。

例えば、単一の引数を持つセレクタの場合、関連するリゾルバは次のキャッシュキーを生成します: [ 123 ]

このキャッシュは、特定のリゾルバの解決ステータスを決定するために使用されます これは、不要な追加のリゾルバの呼び出しを避けるために使用されます(これらはしばしばネットワークリクエストなどの「高コスト」な操作を行います)。

その結果、セレクタを呼び出す際に引数が 一貫性 を保つことが重要です。例えば、デフォルト では、これらの2つの呼び出しは同じキーを使用してキャッシュされませんが、実際には同一である可能性があります:

  1. // Arg as number
  2. getSomeDataById( 123 );
  3. // Arg as string
  4. getSomeDataById( '123' );

これは、unstableNormalizeArgs プロパティを利用して、一貫性を保証し、呼び出し元が不正な型を渡すことから保護する機会です。

以下のセレクタの 3番目 の引数は Number であることを意図しています:

  1. const getItemsSelector = ( name, type, id ) => {
  2. return state.items[ name ][ type ][ id ] || null;
  3. };

しかし、id パラメータが String として渡される可能性があります。この場合、unstableNormalizeArgs メソッド(プロパティ)を セレクタ に定義して、引数を望ましい型に強制することができます。たとえそれらが「不正に」提供されても:

  1. // Define normalization method.
  2. getItemsSelector.__unstableNormalizeArgs = ( args ) {
  3. // "id" argument at the 2nd index
  4. if (args[2] && typeof args[2] === 'string' ) {
  5. args[2] === Number(args[2]);
  6. }
  7. return args;
  8. }

これが整っていれば、次のコードは一貫して動作します:

  1. const getItemsSelector = ( name, type, id ) => {
  2. // here 'id' is now guaranteed to be a number.
  3. return state.items[ name ][ type ][ id ] || null;
  4. };
  5. const getItemsResolver = ( name, type, id ) => {
  6. // 'id' is also guaranteed to be a number in the resolver.
  7. return {};
  8. };
  9. registry.registerStore( 'store', {
  10. // ...
  11. selectors: {
  12. getItems: getItemsSelector,
  13. },
  14. resolvers: {
  15. getItems: getItemsResolver,
  16. },
  17. } );
  18. // Call with correct number type.
  19. registry.select( 'store' ).getItems( 'foo', 'bar', 54 );
  20. // Call with the wrong string type, **but** here we have avoided an
  21. // wanted resolver call because '54' is guaranteed to have been
  22. // coerced to a number by the `__unstableNormalizeArgs` method.
  23. registry.select( 'store' ).getItems( 'foo', 'bar', '54' );

特定のセレクタ呼び出しの引数の一貫性を確保することは、データ層のパフォーマンスを向上させるための重要な最適化です。しかし、この種の問題は、通常、セレクタが引数に可変型を使用しないようにすることで回避できます。

さらに進む

このパッケージへの貢献

これはグーテンベルクプロジェクトの一部である個別のパッケージです。このプロジェクトはモノレポとして整理されています。特定の目的を持つ複数の自己完結型ソフトウェアパッケージで構成されています。このモノレポ内のパッケージはnpmに公開され、WordPressや他のソフトウェアプロジェクトで使用されています。

このパッケージやグーテンベルク全体への貢献について詳しく知りたい場合は、プロジェクトの主な貢献者ガイドをお読みください。