Core Data: Allow useEntityProp setter to accept an updater function#70877
Core Data: Allow useEntityProp setter to accept an updater function#70877Adi-ty wants to merge 3 commits intoWordPress:trunkfrom
Conversation
|
Warning: Type of PR label mismatch To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.
Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task. |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
| _Returns_ | ||
|
|
||
| - `[*, Function, *]`: An array where the first item is the property value, the second is the setter and the third is the full value object from REST API containing more information like `raw`, `rendered` and `protected` props. | ||
| - `[*, Function, *]`: An array where the first item is the property value, the second is the setter (which accepts either a value or an updater function) and the third is the full value object from REST API containing more information like `raw`, `rendered` and `protected` props. |
There was a problem hiding this comment.
This is perhaps a little vague for someone that doesn't know what an updater function usually looks like. A "Usage" section like useEntityRecord has would be really nice.
I would suggest something like the following:
import { useEntityProp } from '@wordpress/core-data';
function MetaUpdater( { postType, postId } ) {
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta', postId );
const handleSyncUpdate = () => {
const result = syncTask();
// Use setter with a static value:
setMeta( { ...meta, taskKey: result } );
};
const handleAsyncUpdate = async () => {
const result = await asyncTask();
// Use setter with an updater function:
setMeta( ( currentMeta ) => { ...currentMeta, taskKey: result } );
};
}There was a problem hiding this comment.
@cr0ybot Thank you for the feedback! I've added your suggested usage section.
What?
This PR implements updater function support for the
useEntityProphook, addressing the stale closure issue.Closes #70748
Why?
When using
useEntityPropin async functions, stale closures can lead to data loss. The existing setter requires a static value, which can become outdated during async operations.How?
Updated Hook Logic: Modified the setValue function to accept updater functions. If newValue is a function, it will receive the current state. This prevents stale data issues by ensuring the setter captures the most recent state when invoked.
Testing Instructions