Add EventPayload::extractValue for NativeAnimated (#49988)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49988

NativeAnimated currently depends on folly::dynamic event payloads for event-driven animations. While some events (e.g., ScrollEvent.h) have an `asDynamic` implementation, not all events do. In practice, NativeAnimated just needs to be able to extract an numeric value from a path to drive an animation.

Rather than converting events to dynamic, or otherwise special casing event handling, this change allows arbitrary payloads to implement `EventPayload::extractValue` to retrieve JS property path values directly from events, without intermediate conversions to dynamic.

## Changelog

[Internal]

Reviewed By: javache

Differential Revision: D71046682

fbshipit-source-id: 3544335ff9d50da87ced015de587b97204173b57
This commit is contained in:
Eric Rozell
2025-03-18 12:12:03 -07:00
committed by Facebook GitHub Bot
parent c99e3a8e60
commit be92588a7f
3 changed files with 31 additions and 0 deletions
@@ -72,6 +72,21 @@ folly::dynamic ScrollEvent::asDynamic() const {
return metrics;
};
std::optional<double> ScrollEvent::extractValue(
const std::vector<std::string>& path) const {
if (path.size() == 1 && path[0] == "zoomScale") {
return zoomScale;
} else if (path.size() == 2 && path[0] == "contentOffset") {
if (path[1] == "x") {
return contentOffset.x;
} else if (path[1] == "y") {
return contentOffset.y;
}
}
return EventPayload::extractValue(path);
}
EventPayloadType ScrollEvent::getType() const {
return EventPayloadType::ScrollEvent;
}
@@ -36,6 +36,9 @@ struct ScrollEvent : public EventPayload {
*/
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
EventPayloadType getType() const override;
std::optional<double> extractValue(
const std::vector<std::string>& path) const override;
};
struct ScrollEndDragEvent : public ScrollEvent {
@@ -10,6 +10,8 @@
#include <jsi/jsi.h>
#include <react/renderer/core/EventPayloadType.h>
#include <optional>
#include <vector>
namespace facebook::react {
@@ -33,6 +35,17 @@ struct EventPayload {
* in `EventPayloadType` and return it from its overriden `getType()` method.
*/
virtual EventPayloadType getType() const = 0;
/**
* Used to extract numeric values from the event payload based on
* property path names as they will exist in JavaScript. This can
* be used in conjunction with listeners on EventEmitters to do
* things like drive native animations.
*/
virtual std::optional<double> extractValue(
const std::vector<std::string>& /* path */) const {
return std::nullopt;
}
};
using SharedEventPayload = std::shared_ptr<const EventPayload>;