Meet the Data API

Meet the Data API

(Also known as "The Ultimate Beginner's Guide to the Gutenberg Data API")

One of the most challenging pieces of building powerful Gutenberg integrations is working with the WordPress Data API. The Data API is how you get data in and out of Gutenberg, track changes across blocks, and execute events around the editor. If you’re unfamiliar with the Data API (or Redux, the technology that powers it), this talk is for you. You’ll learn why the Data API matters, how it’s architected, when and how to use it, and much more.

38bc9be7f4f140d1f719c1faeed29a6c?s=128

Chris Van Patten

November 09, 2019
Tweet

Transcript

  1. Meet the Data API

  2. Meet the Data API Me

  3. @ChrisVanPatten

  4. @BusinessOfCMS businessofcms.com

  5. REACT

  6. REACT (is a state management library)

  7. Props vs State

  8. Props <Component>

  9. Props <Component>

  10. Props <Component>

  11. Props <Component> State

  12. Props <Component> <Component> Props

  13. Props <Component> <Component> Props

  14. Props <Component> <Component> Props <Co Props

  15. Prop drilling has its limits.

  16. Meet Redux

  17. Meet Redux The WordPress Data API

  18. Data Store <Component> <Component>

  19. Get and modify data in a store

  20. Get and modify data in a store Subscribe your component

    to changes in a store
  21. Get and modify data in a store Subscribe your component

    to changes in a store Send changes from your component to a store
  22. Get and modify data in a store Subscribe your component

    to changes in a store Send changes from your component to a store Register your own store
  23. Get and modify data in a store Subscribe your component

    to changes in a store Send changes from your component to a store Register your own store
  24. Select

  25. Demo

  26. Dispatch

  27. Demo

  28. Get and modify data in a store Subscribe your component

    to changes in a store Send changes from your component to a store Register your own store
  29. useSelect

  30. import { useSelect } from '@wordpress/data';

  31. import { useSelect } from '@wordpress/data'; const Edit = (

    props ) => { };
  32. import { useSelect } from '@wordpress/data'; const Edit = (

    props ) => { const blocks = useSelect( ); };
  33. import { useSelect } from '@wordpress/data'; const Edit = (

    props ) => { const blocks = useSelect( ( select ) => ( select( 'core/block-editor' ).getBlocks() ) ); };
  34. import { useSelect } from '@wordpress/data'; const Edit = (

    props ) => { const blocks = useSelect( ( select ) => ( select( 'core/block-editor' ).getBlocks() ) ); return ( <p>{ JSON.stringify( blocks ) }</p> ); };
  35. import { useSelect } from '@wordpress/data'; const Edit = (

    props ) => { const blocks = useSelect( ( select ) => ( select( 'core/block-editor' ).getBlocks() ) ); return ( <p>{ JSON.stringify( blocks ) }</p> ); };
  36. Get and modify data in a store Subscribe your component

    to changes in a store Send changes from your component to a store Register your own store
  37. useDispatch

  38. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data';
  39. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { };
  40. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { } = useDispatch( ); };
  41. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { } = useDispatch( 'core/edit-post' ); };
  42. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { openGeneralSidebar } = useDispatch( 'core/edit-post' ); };
  43. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { openGeneralSidebar } = useDispatch( 'core/edit-post' ); return ( ); };
  44. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { openGeneralSidebar } = useDispatch( 'core/edit-post' ); return ( <Button isPrimary onClick={ } > Click to open sidebar! </Button> ); };
  45. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { openGeneralSidebar } = useDispatch( 'core/edit-post' ); return ( <Button isPrimary onClick={ () => openGeneralSidebar( 'edit-post/document' ) } > Click to open sidebar! </Button> ); };
  46. import { Button } from '@wordpress/components'; import { useDispatch }

    from '@wordpress/data'; const Edit = ( props ) => { const { openGeneralSidebar } = useDispatch( 'core/edit-post' ); return ( <Button isPrimary onClick={ () => openGeneralSidebar( 'edit-post/document' ) } > Click to open sidebar! </Button> ); };
  47. Get and modify data in a store Subscribe your component

    to changes in a store Send changes from your component to a store Register your own store
  48. Store

  49. store { actions, reducer, selectors, }

  50. State

  51. Action

  52. Reducer

  53. Selector

  54. /** * WordPress dependencies */ import { registerStore } from

    '@wordpress/data';
  55. const defaultState = { talks: {}, }; /** * WordPress

    dependencies */ import { registerStore } from '@wordpress/data';
  56. const actions = { addTalk( talkName, talkDescription ) { return

    { type: 'ADD_TALK', talkName, talkDescription, }; }, }; const defaultState = { talks: {}, };
  57. const reducer = ( state = defaultState, action ) =>

    { switch ( action.type ) { case 'ADD_TALK': return { ...state, talks: { ...state.talks, [ action.talkName ]: action.talkDescription, }, }; } return state; }; };
  58. const selectors = { getTalks( state ) { const {

    talks } = state; return talks; }, getTalk( state, talkName ) { const { talks } = state; return talks[ talkName ] || null; }, }; return state; };
  59. registerStore( 'wordcamp/seattle', { actions, reducer, selectors, }, ); return talks[

    talkName ] || null; }, };
  60. /** * WordPress dependencies */ import { registerStore } from

    '@wordpress/data'; const defaultState = { talks: {}, }; const actions = { addTalk( talkName, talkDescription ) { return { type: 'ADD_TALK', talkName, talkDescription, }; }, }; const reducer = ( state = defaultState, action ) => { switch ( action.type ) { case 'ADD_TALK': return { ...state, talks: { ...state.talks, [ action.talkName ]: action.talkDescription, }, }; } return state; }; const selectors = { getTalks( state ) { const { talks } = state; return talks; }, getTalk( state, talkName ) { const { talks } = state; return talks[ talkName ] || null; }, }; registerStore( 'wordcamp/seattle', { actions, reducer, selectors, }, );
  61. Demo

  62. Thanks!

  63. @ChrisVanPatten cvp.me/wcsea2019