@wordpress/server-side-render 5.22.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 6.0.0 (2025-05-22)
6
+
7
+ ### Breaking Changes
8
+
9
+ - The `LoadingResponsePlaceholder` prop will no longer receive `showLoader`. The spinner rendering logic is now located in the same component ([#70147](https://github.com/WordPress/gutenberg/pull/70147)).
10
+
11
+ ## 5.23.0 (2025-05-07)
12
+
13
+ ### Bug Fixes
14
+
15
+ - Fix `ServerSideRender` not updating when attributes change by properly implementing debounced fetch with refs ([#69237](https://github.com/WordPress/gutenberg/pull/69237)).
16
+
5
17
  ## 5.22.0 (2025-04-11)
6
18
 
7
19
  ## 5.21.0 (2025-03-27)
@@ -80,8 +80,21 @@ function DefaultErrorResponsePlaceholder({
80
80
  }
81
81
  function DefaultLoadingResponsePlaceholder({
82
82
  children,
83
- showLoader
83
+ isLoading
84
84
  }) {
85
+ const [showLoader, setShowLoader] = (0, _element.useState)(false);
86
+ (0, _element.useEffect)(() => {
87
+ if (!isLoading) {
88
+ setShowLoader(false);
89
+ return;
90
+ }
91
+
92
+ // Schedule showing the Spinner after 1 second.
93
+ const timeout = setTimeout(() => {
94
+ setShowLoader(true);
95
+ }, 1000);
96
+ return () => clearTimeout(timeout);
97
+ }, [isLoading]);
85
98
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
86
99
  style: {
87
100
  position: 'relative'
@@ -105,33 +118,33 @@ function DefaultLoadingResponsePlaceholder({
105
118
  }
106
119
  function ServerSideRender(props) {
107
120
  const {
108
- attributes,
109
- block,
110
121
  className,
111
- httpMethod = 'GET',
112
- urlQueryArgs,
113
- skipBlockSupportAttributes = false,
114
122
  EmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,
115
123
  ErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,
116
124
  LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder
117
125
  } = props;
118
126
  const isMountedRef = (0, _element.useRef)(false);
119
- const [showLoader, setShowLoader] = (0, _element.useState)(false);
120
127
  const fetchRequestRef = (0, _element.useRef)();
121
128
  const [response, setResponse] = (0, _element.useState)(null);
122
129
  const prevProps = (0, _compose.usePrevious)(props);
123
130
  const [isLoading, setIsLoading] = (0, _element.useState)(false);
124
- function fetchData() {
131
+ const latestPropsRef = (0, _element.useRef)(props);
132
+ (0, _element.useLayoutEffect)(() => {
133
+ latestPropsRef.current = props;
134
+ }, [props]);
135
+ const fetchData = (0, _element.useCallback)(() => {
125
136
  var _sanitizedAttributes, _sanitizedAttributes2;
126
137
  if (!isMountedRef.current) {
127
138
  return;
128
139
  }
140
+ const {
141
+ attributes,
142
+ block,
143
+ skipBlockSupportAttributes = false,
144
+ httpMethod = 'GET',
145
+ urlQueryArgs
146
+ } = latestPropsRef.current;
129
147
  setIsLoading(true);
130
-
131
- // Schedule showing the Spinner after 1 second.
132
- const timeout = setTimeout(() => {
133
- setShowLoader(true);
134
- }, 1000);
135
148
  let sanitizedAttributes = attributes && (0, _blocks.__experimentalSanitizeBlockAttributes)(block, attributes);
136
149
  if (skipBlockSupportAttributes) {
137
150
  sanitizedAttributes = removeBlockSupportAttributes(sanitizedAttributes);
@@ -166,13 +179,10 @@ function ServerSideRender(props) {
166
179
  }).finally(() => {
167
180
  if (isMountedRef.current && fetchRequest === fetchRequestRef.current) {
168
181
  setIsLoading(false);
169
- // Cancel the timeout to show the Spinner.
170
- setShowLoader(false);
171
- clearTimeout(timeout);
172
182
  }
173
183
  });
174
184
  return fetchRequest;
175
- }
185
+ }, []);
176
186
  const debouncedFetchData = (0, _compose.useDebounce)(fetchData, 500);
177
187
 
178
188
  // When the component unmounts, set isMountedRef to false. This will
@@ -194,12 +204,12 @@ function ServerSideRender(props) {
194
204
  });
195
205
  const hasResponse = !!response;
196
206
  const hasEmptyResponse = response === '';
197
- const hasError = response?.error;
207
+ const hasError = !!response?.error;
198
208
  if (isLoading) {
199
209
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(LoadingResponsePlaceholder, {
200
210
  ...props,
201
- showLoader: showLoader,
202
- children: hasResponse && /*#__PURE__*/(0, _jsxRuntime.jsx)(_element.RawHTML, {
211
+ isLoading: isLoading,
212
+ children: hasResponse && !hasError && /*#__PURE__*/(0, _jsxRuntime.jsx)(_element.RawHTML, {
203
213
  className: className,
204
214
  children: response
205
215
  })
@@ -1 +1 @@
1
- {"version":3,"names":["_es","_interopRequireDefault","require","_compose","_element","_i18n","_apiFetch","_url","_components","_blocks","_jsxRuntime","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","addQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","jsx","Placeholder","children","__","DefaultErrorResponsePlaceholder","response","errorMessage","sprintf","errorMsg","DefaultLoadingResponsePlaceholder","showLoader","jsxs","position","top","left","marginTop","marginLeft","Spinner","opacity","ServerSideRender","props","httpMethod","skipBlockSupportAttributes","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","useRef","setShowLoader","useState","fetchRequestRef","setResponse","prevProps","usePrevious","isLoading","setIsLoading","fetchData","_sanitizedAttributes","_sanitizedAttributes2","current","timeout","setTimeout","sanitizedAttributes","__experimentalSanitizeBlockAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","apiFetch","method","then","fetchResponse","rendered","catch","error","message","finally","clearTimeout","debouncedFetchData","useDebounce","useEffect","undefined","fastDeepEqual","hasResponse","hasEmptyResponse","hasError","RawHTML"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport { RawHTML, useEffect, useRef, useState } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, showLoader } ) {\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tattributes,\n\t\tblock,\n\t\tclassName,\n\t\thttpMethod = 'GET',\n\t\turlQueryArgs,\n\t\tskipBlockSupportAttributes = false,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading( true );\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t\t// Cancel the timeout to show the Spinner.\n\t\t\t\t\tsetShowLoader( false );\n\t\t\t\t\tclearTimeout( timeout );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>\n\t\t\t\t{ hasResponse && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_es","_interopRequireDefault","require","_compose","_element","_i18n","_apiFetch","_url","_components","_blocks","_jsxRuntime","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","addQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","jsx","Placeholder","children","__","DefaultErrorResponsePlaceholder","response","errorMessage","sprintf","errorMsg","DefaultLoadingResponsePlaceholder","isLoading","showLoader","setShowLoader","useState","useEffect","timeout","setTimeout","clearTimeout","jsxs","position","top","left","marginTop","marginLeft","Spinner","opacity","ServerSideRender","props","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","useRef","fetchRequestRef","setResponse","prevProps","usePrevious","setIsLoading","latestPropsRef","useLayoutEffect","current","fetchData","useCallback","_sanitizedAttributes","_sanitizedAttributes2","skipBlockSupportAttributes","httpMethod","sanitizedAttributes","__experimentalSanitizeBlockAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","apiFetch","method","then","fetchResponse","rendered","catch","error","message","finally","debouncedFetchData","useDebounce","undefined","fastDeepEqual","hasResponse","hasEmptyResponse","hasError","RawHTML"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport {\n\tRawHTML,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, isLoading } ) {\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\n\tuseEffect( () => {\n\t\tif ( ! isLoading ) {\n\t\t\tsetShowLoader( false );\n\t\t\treturn;\n\t\t}\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\t\treturn () => clearTimeout( timeout );\n\t}, [ isLoading ] );\n\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tclassName,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\tconst latestPropsRef = useRef( props );\n\n\tuseLayoutEffect( () => {\n\t\tlatestPropsRef.current = props;\n\t}, [ props ] );\n\n\tconst fetchData = useCallback( () => {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst {\n\t\t\tattributes,\n\t\t\tblock,\n\t\t\tskipBlockSupportAttributes = false,\n\t\t\thttpMethod = 'GET',\n\t\t\turlQueryArgs,\n\t\t} = latestPropsRef.current;\n\n\t\tsetIsLoading( true );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}, [] );\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = !! response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } isLoading={ isLoading }>\n\t\t\t\t{ hasResponse && ! hasError && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -7,7 +7,7 @@ import fastDeepEqual from 'fast-deep-equal/es6';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useDebounce, usePrevious } from '@wordpress/compose';
10
- import { RawHTML, useEffect, useRef, useState } from '@wordpress/element';
10
+ import { RawHTML, useCallback, useEffect, useLayoutEffect, useRef, useState } from '@wordpress/element';
11
11
  import { __, sprintf } from '@wordpress/i18n';
12
12
  import apiFetch from '@wordpress/api-fetch';
13
13
  import { addQueryArgs } from '@wordpress/url';
@@ -70,8 +70,21 @@ function DefaultErrorResponsePlaceholder({
70
70
  }
71
71
  function DefaultLoadingResponsePlaceholder({
72
72
  children,
73
- showLoader
73
+ isLoading
74
74
  }) {
75
+ const [showLoader, setShowLoader] = useState(false);
76
+ useEffect(() => {
77
+ if (!isLoading) {
78
+ setShowLoader(false);
79
+ return;
80
+ }
81
+
82
+ // Schedule showing the Spinner after 1 second.
83
+ const timeout = setTimeout(() => {
84
+ setShowLoader(true);
85
+ }, 1000);
86
+ return () => clearTimeout(timeout);
87
+ }, [isLoading]);
75
88
  return /*#__PURE__*/_jsxs("div", {
76
89
  style: {
77
90
  position: 'relative'
@@ -95,33 +108,33 @@ function DefaultLoadingResponsePlaceholder({
95
108
  }
96
109
  export default function ServerSideRender(props) {
97
110
  const {
98
- attributes,
99
- block,
100
111
  className,
101
- httpMethod = 'GET',
102
- urlQueryArgs,
103
- skipBlockSupportAttributes = false,
104
112
  EmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,
105
113
  ErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,
106
114
  LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder
107
115
  } = props;
108
116
  const isMountedRef = useRef(false);
109
- const [showLoader, setShowLoader] = useState(false);
110
117
  const fetchRequestRef = useRef();
111
118
  const [response, setResponse] = useState(null);
112
119
  const prevProps = usePrevious(props);
113
120
  const [isLoading, setIsLoading] = useState(false);
114
- function fetchData() {
121
+ const latestPropsRef = useRef(props);
122
+ useLayoutEffect(() => {
123
+ latestPropsRef.current = props;
124
+ }, [props]);
125
+ const fetchData = useCallback(() => {
115
126
  var _sanitizedAttributes, _sanitizedAttributes2;
116
127
  if (!isMountedRef.current) {
117
128
  return;
118
129
  }
130
+ const {
131
+ attributes,
132
+ block,
133
+ skipBlockSupportAttributes = false,
134
+ httpMethod = 'GET',
135
+ urlQueryArgs
136
+ } = latestPropsRef.current;
119
137
  setIsLoading(true);
120
-
121
- // Schedule showing the Spinner after 1 second.
122
- const timeout = setTimeout(() => {
123
- setShowLoader(true);
124
- }, 1000);
125
138
  let sanitizedAttributes = attributes && __experimentalSanitizeBlockAttributes(block, attributes);
126
139
  if (skipBlockSupportAttributes) {
127
140
  sanitizedAttributes = removeBlockSupportAttributes(sanitizedAttributes);
@@ -156,13 +169,10 @@ export default function ServerSideRender(props) {
156
169
  }).finally(() => {
157
170
  if (isMountedRef.current && fetchRequest === fetchRequestRef.current) {
158
171
  setIsLoading(false);
159
- // Cancel the timeout to show the Spinner.
160
- setShowLoader(false);
161
- clearTimeout(timeout);
162
172
  }
163
173
  });
164
174
  return fetchRequest;
165
- }
175
+ }, []);
166
176
  const debouncedFetchData = useDebounce(fetchData, 500);
167
177
 
168
178
  // When the component unmounts, set isMountedRef to false. This will
@@ -184,12 +194,12 @@ export default function ServerSideRender(props) {
184
194
  });
185
195
  const hasResponse = !!response;
186
196
  const hasEmptyResponse = response === '';
187
- const hasError = response?.error;
197
+ const hasError = !!response?.error;
188
198
  if (isLoading) {
189
199
  return /*#__PURE__*/_jsx(LoadingResponsePlaceholder, {
190
200
  ...props,
191
- showLoader: showLoader,
192
- children: hasResponse && /*#__PURE__*/_jsx(RawHTML, {
201
+ isLoading: isLoading,
202
+ children: hasResponse && !hasError && /*#__PURE__*/_jsx(RawHTML, {
193
203
  className: className,
194
204
  children: response
195
205
  })
@@ -1 +1 @@
1
- {"version":3,"names":["fastDeepEqual","useDebounce","usePrevious","RawHTML","useEffect","useRef","useState","__","sprintf","apiFetch","addQueryArgs","Placeholder","Spinner","__experimentalSanitizeBlockAttributes","jsx","_jsx","jsxs","_jsxs","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","children","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","showLoader","position","top","left","marginTop","marginLeft","opacity","ServerSideRender","props","httpMethod","skipBlockSupportAttributes","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","setShowLoader","fetchRequestRef","setResponse","prevProps","isLoading","setIsLoading","fetchData","_sanitizedAttributes","_sanitizedAttributes2","current","timeout","setTimeout","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","finally","clearTimeout","debouncedFetchData","undefined","hasResponse","hasEmptyResponse","hasError"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport { RawHTML, useEffect, useRef, useState } from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, showLoader } ) {\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tattributes,\n\t\tblock,\n\t\tclassName,\n\t\thttpMethod = 'GET',\n\t\turlQueryArgs,\n\t\tskipBlockSupportAttributes = false,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\n\tfunction fetchData() {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetIsLoading( true );\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t\t// Cancel the timeout to show the Spinner.\n\t\t\t\t\tsetShowLoader( false );\n\t\t\t\t\tclearTimeout( timeout );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>\n\t\t\t\t{ hasResponse && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["fastDeepEqual","useDebounce","usePrevious","RawHTML","useCallback","useEffect","useLayoutEffect","useRef","useState","__","sprintf","apiFetch","addQueryArgs","Placeholder","Spinner","__experimentalSanitizeBlockAttributes","jsx","_jsx","jsxs","_jsxs","EMPTY_OBJECT","rendererPath","block","attributes","urlQueryArgs","context","removeBlockSupportAttributes","backgroundColor","borderColor","fontFamily","fontSize","gradient","textColor","className","restAttributes","border","color","elements","spacing","typography","restStyles","style","DefaultEmptyResponsePlaceholder","children","DefaultErrorResponsePlaceholder","response","errorMessage","errorMsg","DefaultLoadingResponsePlaceholder","isLoading","showLoader","setShowLoader","timeout","setTimeout","clearTimeout","position","top","left","marginTop","marginLeft","opacity","ServerSideRender","props","EmptyResponsePlaceholder","ErrorResponsePlaceholder","LoadingResponsePlaceholder","isMountedRef","fetchRequestRef","setResponse","prevProps","setIsLoading","latestPropsRef","current","fetchData","_sanitizedAttributes","_sanitizedAttributes2","skipBlockSupportAttributes","httpMethod","sanitizedAttributes","isPostRequest","urlAttributes","path","data","fetchRequest","method","then","fetchResponse","rendered","catch","error","message","finally","debouncedFetchData","undefined","hasResponse","hasEmptyResponse","hasError"],"sources":["@wordpress/server-side-render/src/server-side-render.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\n\n/**\n * WordPress dependencies\n */\nimport { useDebounce, usePrevious } from '@wordpress/compose';\nimport {\n\tRawHTML,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __, sprintf } from '@wordpress/i18n';\nimport apiFetch from '@wordpress/api-fetch';\nimport { addQueryArgs } from '@wordpress/url';\nimport { Placeholder, Spinner } from '@wordpress/components';\nimport { __experimentalSanitizeBlockAttributes } from '@wordpress/blocks';\n\nconst EMPTY_OBJECT = {};\n\nexport function rendererPath( block, attributes = null, urlQueryArgs = {} ) {\n\treturn addQueryArgs( `/wp/v2/block-renderer/${ block }`, {\n\t\tcontext: 'edit',\n\t\t...( null !== attributes ? { attributes } : {} ),\n\t\t...urlQueryArgs,\n\t} );\n}\n\nexport function removeBlockSupportAttributes( attributes ) {\n\tconst {\n\t\tbackgroundColor,\n\t\tborderColor,\n\t\tfontFamily,\n\t\tfontSize,\n\t\tgradient,\n\t\ttextColor,\n\t\tclassName,\n\t\t...restAttributes\n\t} = attributes;\n\n\tconst { border, color, elements, spacing, typography, ...restStyles } =\n\t\tattributes?.style || EMPTY_OBJECT;\n\n\treturn {\n\t\t...restAttributes,\n\t\tstyle: restStyles,\n\t};\n}\n\nfunction DefaultEmptyResponsePlaceholder( { className } ) {\n\treturn (\n\t\t<Placeholder className={ className }>\n\t\t\t{ __( 'Block rendered as empty.' ) }\n\t\t</Placeholder>\n\t);\n}\n\nfunction DefaultErrorResponsePlaceholder( { response, className } ) {\n\tconst errorMessage = sprintf(\n\t\t// translators: %s: error message describing the problem\n\t\t__( 'Error loading block: %s' ),\n\t\tresponse.errorMsg\n\t);\n\treturn <Placeholder className={ className }>{ errorMessage }</Placeholder>;\n}\n\nfunction DefaultLoadingResponsePlaceholder( { children, isLoading } ) {\n\tconst [ showLoader, setShowLoader ] = useState( false );\n\n\tuseEffect( () => {\n\t\tif ( ! isLoading ) {\n\t\t\tsetShowLoader( false );\n\t\t\treturn;\n\t\t}\n\n\t\t// Schedule showing the Spinner after 1 second.\n\t\tconst timeout = setTimeout( () => {\n\t\t\tsetShowLoader( true );\n\t\t}, 1000 );\n\t\treturn () => clearTimeout( timeout );\n\t}, [ isLoading ] );\n\n\treturn (\n\t\t<div style={ { position: 'relative' } }>\n\t\t\t{ showLoader && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: '50%',\n\t\t\t\t\t\tleft: '50%',\n\t\t\t\t\t\tmarginTop: '-9px',\n\t\t\t\t\t\tmarginLeft: '-9px',\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<Spinner />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t\t<div style={ { opacity: showLoader ? '0.3' : 1 } }>\n\t\t\t\t{ children }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default function ServerSideRender( props ) {\n\tconst {\n\t\tclassName,\n\t\tEmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,\n\t\tErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,\n\t\tLoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,\n\t} = props;\n\n\tconst isMountedRef = useRef( false );\n\tconst fetchRequestRef = useRef();\n\tconst [ response, setResponse ] = useState( null );\n\tconst prevProps = usePrevious( props );\n\tconst [ isLoading, setIsLoading ] = useState( false );\n\tconst latestPropsRef = useRef( props );\n\n\tuseLayoutEffect( () => {\n\t\tlatestPropsRef.current = props;\n\t}, [ props ] );\n\n\tconst fetchData = useCallback( () => {\n\t\tif ( ! isMountedRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst {\n\t\t\tattributes,\n\t\t\tblock,\n\t\t\tskipBlockSupportAttributes = false,\n\t\t\thttpMethod = 'GET',\n\t\t\turlQueryArgs,\n\t\t} = latestPropsRef.current;\n\n\t\tsetIsLoading( true );\n\n\t\tlet sanitizedAttributes =\n\t\t\tattributes &&\n\t\t\t__experimentalSanitizeBlockAttributes( block, attributes );\n\n\t\tif ( skipBlockSupportAttributes ) {\n\t\t\tsanitizedAttributes =\n\t\t\t\tremoveBlockSupportAttributes( sanitizedAttributes );\n\t\t}\n\n\t\t// If httpMethod is 'POST', send the attributes in the request body instead of the URL.\n\t\t// This allows sending a larger attributes object than in a GET request, where the attributes are in the URL.\n\t\tconst isPostRequest = 'POST' === httpMethod;\n\t\tconst urlAttributes = isPostRequest\n\t\t\t? null\n\t\t\t: sanitizedAttributes ?? null;\n\t\tconst path = rendererPath( block, urlAttributes, urlQueryArgs );\n\t\tconst data = isPostRequest\n\t\t\t? { attributes: sanitizedAttributes ?? null }\n\t\t\t: null;\n\n\t\t// Store the latest fetch request so that when we process it, we can\n\t\t// check if it is the current request, to avoid race conditions on slow networks.\n\t\tconst fetchRequest = ( fetchRequestRef.current = apiFetch( {\n\t\t\tpath,\n\t\t\tdata,\n\t\t\tmethod: isPostRequest ? 'POST' : 'GET',\n\t\t} )\n\t\t\t.then( ( fetchResponse ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current &&\n\t\t\t\t\tfetchResponse\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( fetchResponse.rendered );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( ( error ) => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetResponse( {\n\t\t\t\t\t\terror: true,\n\t\t\t\t\t\terrorMsg: error.message,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.finally( () => {\n\t\t\t\tif (\n\t\t\t\t\tisMountedRef.current &&\n\t\t\t\t\tfetchRequest === fetchRequestRef.current\n\t\t\t\t) {\n\t\t\t\t\tsetIsLoading( false );\n\t\t\t\t}\n\t\t\t} ) );\n\n\t\treturn fetchRequest;\n\t}, [] );\n\n\tconst debouncedFetchData = useDebounce( fetchData, 500 );\n\n\t// When the component unmounts, set isMountedRef to false. This will\n\t// let the async fetch callbacks know when to stop.\n\tuseEffect( () => {\n\t\tisMountedRef.current = true;\n\t\treturn () => {\n\t\t\tisMountedRef.current = false;\n\t\t};\n\t}, [] );\n\n\tuseEffect( () => {\n\t\t// Don't debounce the first fetch. This ensures that the first render\n\t\t// shows data as soon as possible.\n\t\tif ( prevProps === undefined ) {\n\t\t\tfetchData();\n\t\t} else if ( ! fastDeepEqual( prevProps, props ) ) {\n\t\t\tdebouncedFetchData();\n\t\t}\n\t} );\n\n\tconst hasResponse = !! response;\n\tconst hasEmptyResponse = response === '';\n\tconst hasError = !! response?.error;\n\n\tif ( isLoading ) {\n\t\treturn (\n\t\t\t<LoadingResponsePlaceholder { ...props } isLoading={ isLoading }>\n\t\t\t\t{ hasResponse && ! hasError && (\n\t\t\t\t\t<RawHTML className={ className }>{ response }</RawHTML>\n\t\t\t\t) }\n\t\t\t</LoadingResponsePlaceholder>\n\t\t);\n\t}\n\n\tif ( hasEmptyResponse || ! hasResponse ) {\n\t\treturn <EmptyResponsePlaceholder { ...props } />;\n\t}\n\n\tif ( hasError ) {\n\t\treturn <ErrorResponsePlaceholder response={ response } { ...props } />;\n\t}\n\n\treturn <RawHTML className={ className }>{ response }</RawHTML>;\n}\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/server-side-render",
3
- "version": "5.22.0",
3
+ "version": "6.0.0",
4
4
  "description": "The component used with WordPress to server-side render a preview of dynamic blocks to display in the editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -29,15 +29,15 @@
29
29
  "wpScript": true,
30
30
  "dependencies": {
31
31
  "@babel/runtime": "7.25.7",
32
- "@wordpress/api-fetch": "^7.22.0",
33
- "@wordpress/blocks": "^14.11.0",
34
- "@wordpress/components": "^29.8.0",
35
- "@wordpress/compose": "^7.22.0",
36
- "@wordpress/data": "^10.22.0",
37
- "@wordpress/deprecated": "^4.22.0",
38
- "@wordpress/element": "^6.22.0",
39
- "@wordpress/i18n": "^5.22.0",
40
- "@wordpress/url": "^4.22.0",
32
+ "@wordpress/api-fetch": "^7.24.0",
33
+ "@wordpress/blocks": "^14.13.0",
34
+ "@wordpress/components": "^29.10.0",
35
+ "@wordpress/compose": "^7.24.0",
36
+ "@wordpress/data": "^10.24.0",
37
+ "@wordpress/deprecated": "^4.24.0",
38
+ "@wordpress/element": "^6.24.0",
39
+ "@wordpress/i18n": "^5.24.0",
40
+ "@wordpress/url": "^4.24.0",
41
41
  "fast-deep-equal": "^3.1.3"
42
42
  },
43
43
  "peerDependencies": {
@@ -47,5 +47,5 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "gitHead": "01a314d7e46a50101e328fdb11959c441e49372d"
50
+ "gitHead": "9c03d1458cae76792ae15e67b421205836bf4393"
51
51
  }
@@ -7,7 +7,14 @@ import fastDeepEqual from 'fast-deep-equal/es6';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useDebounce, usePrevious } from '@wordpress/compose';
10
- import { RawHTML, useEffect, useRef, useState } from '@wordpress/element';
10
+ import {
11
+ RawHTML,
12
+ useCallback,
13
+ useEffect,
14
+ useLayoutEffect,
15
+ useRef,
16
+ useState,
17
+ } from '@wordpress/element';
11
18
  import { __, sprintf } from '@wordpress/i18n';
12
19
  import apiFetch from '@wordpress/api-fetch';
13
20
  import { addQueryArgs } from '@wordpress/url';
@@ -62,7 +69,22 @@ function DefaultErrorResponsePlaceholder( { response, className } ) {
62
69
  return <Placeholder className={ className }>{ errorMessage }</Placeholder>;
63
70
  }
64
71
 
65
- function DefaultLoadingResponsePlaceholder( { children, showLoader } ) {
72
+ function DefaultLoadingResponsePlaceholder( { children, isLoading } ) {
73
+ const [ showLoader, setShowLoader ] = useState( false );
74
+
75
+ useEffect( () => {
76
+ if ( ! isLoading ) {
77
+ setShowLoader( false );
78
+ return;
79
+ }
80
+
81
+ // Schedule showing the Spinner after 1 second.
82
+ const timeout = setTimeout( () => {
83
+ setShowLoader( true );
84
+ }, 1000 );
85
+ return () => clearTimeout( timeout );
86
+ }, [ isLoading ] );
87
+
66
88
  return (
67
89
  <div style={ { position: 'relative' } }>
68
90
  { showLoader && (
@@ -87,35 +109,37 @@ function DefaultLoadingResponsePlaceholder( { children, showLoader } ) {
87
109
 
88
110
  export default function ServerSideRender( props ) {
89
111
  const {
90
- attributes,
91
- block,
92
112
  className,
93
- httpMethod = 'GET',
94
- urlQueryArgs,
95
- skipBlockSupportAttributes = false,
96
113
  EmptyResponsePlaceholder = DefaultEmptyResponsePlaceholder,
97
114
  ErrorResponsePlaceholder = DefaultErrorResponsePlaceholder,
98
115
  LoadingResponsePlaceholder = DefaultLoadingResponsePlaceholder,
99
116
  } = props;
100
117
 
101
118
  const isMountedRef = useRef( false );
102
- const [ showLoader, setShowLoader ] = useState( false );
103
119
  const fetchRequestRef = useRef();
104
120
  const [ response, setResponse ] = useState( null );
105
121
  const prevProps = usePrevious( props );
106
122
  const [ isLoading, setIsLoading ] = useState( false );
123
+ const latestPropsRef = useRef( props );
124
+
125
+ useLayoutEffect( () => {
126
+ latestPropsRef.current = props;
127
+ }, [ props ] );
107
128
 
108
- function fetchData() {
129
+ const fetchData = useCallback( () => {
109
130
  if ( ! isMountedRef.current ) {
110
131
  return;
111
132
  }
112
133
 
113
- setIsLoading( true );
134
+ const {
135
+ attributes,
136
+ block,
137
+ skipBlockSupportAttributes = false,
138
+ httpMethod = 'GET',
139
+ urlQueryArgs,
140
+ } = latestPropsRef.current;
114
141
 
115
- // Schedule showing the Spinner after 1 second.
116
- const timeout = setTimeout( () => {
117
- setShowLoader( true );
118
- }, 1000 );
142
+ setIsLoading( true );
119
143
 
120
144
  let sanitizedAttributes =
121
145
  attributes &&
@@ -170,14 +194,11 @@ export default function ServerSideRender( props ) {
170
194
  fetchRequest === fetchRequestRef.current
171
195
  ) {
172
196
  setIsLoading( false );
173
- // Cancel the timeout to show the Spinner.
174
- setShowLoader( false );
175
- clearTimeout( timeout );
176
197
  }
177
198
  } ) );
178
199
 
179
200
  return fetchRequest;
180
- }
201
+ }, [] );
181
202
 
182
203
  const debouncedFetchData = useDebounce( fetchData, 500 );
183
204
 
@@ -202,12 +223,12 @@ export default function ServerSideRender( props ) {
202
223
 
203
224
  const hasResponse = !! response;
204
225
  const hasEmptyResponse = response === '';
205
- const hasError = response?.error;
226
+ const hasError = !! response?.error;
206
227
 
207
228
  if ( isLoading ) {
208
229
  return (
209
- <LoadingResponsePlaceholder { ...props } showLoader={ showLoader }>
210
- { hasResponse && (
230
+ <LoadingResponsePlaceholder { ...props } isLoading={ isLoading }>
231
+ { hasResponse && ! hasError && (
211
232
  <RawHTML className={ className }>{ response }</RawHTML>
212
233
  ) }
213
234
  </LoadingResponsePlaceholder>