mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Introduce Element<>.stateData API
Summary: Changelog: [Internal] Previous interface `Element<>.state` wasn't usable because creating ConcreteState requires ownership of component descriptor and family. Family isn't created until later and it isn't accessible to the caller. To work around this shortcoming, we create `stateData` rather than state. Reviewed By: JoshuaGross Differential Revision: D23028296 fbshipit-source-id: fba35ea8e6986b77379b1dddaa37012f4234f86e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8d6b41e9bc
commit
6db19b036e
@@ -30,10 +30,8 @@ ShadowNode::Unshared ComponentBuilder::build(
|
||||
elementFragment.tag, elementFragment.surfaceId, nullptr},
|
||||
nullptr);
|
||||
|
||||
auto state = elementFragment.state
|
||||
? elementFragment.state
|
||||
: componentDescriptor.createInitialState(
|
||||
ShadowNodeFragment{elementFragment.props}, family);
|
||||
auto state = componentDescriptor.createInitialState(
|
||||
ShadowNodeFragment{elementFragment.props}, family);
|
||||
|
||||
auto constShadowNode = componentDescriptor.createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
@@ -42,6 +40,16 @@ ShadowNode::Unshared ComponentBuilder::build(
|
||||
state},
|
||||
family);
|
||||
|
||||
if (elementFragment.stateCallback) {
|
||||
auto newState = componentDescriptor.createState(
|
||||
*family, elementFragment.stateCallback());
|
||||
constShadowNode = componentDescriptor.cloneShadowNode(
|
||||
*constShadowNode,
|
||||
ShadowNodeFragment{ShadowNodeFragment::propsPlaceholder(),
|
||||
ShadowNodeFragment::childrenPlaceholder(),
|
||||
newState});
|
||||
}
|
||||
|
||||
auto shadowNode = std::const_pointer_cast<ShadowNode>(constShadowNode);
|
||||
|
||||
if (elementFragment.referenceCallback) {
|
||||
|
||||
@@ -33,6 +33,7 @@ class Element final {
|
||||
using ConcreteProps = typename ShadowNodeT::ConcreteProps;
|
||||
using SharedConcreteProps = std::shared_ptr<ConcreteProps const>;
|
||||
using ConcreteState = typename ShadowNodeT::ConcreteState;
|
||||
using ConcreteStateData = typename ShadowNodeT::ConcreteStateData;
|
||||
using SharedConcreteState = std::shared_ptr<ConcreteState const>;
|
||||
using ConcreteShadowNode = ShadowNodeT;
|
||||
using ConcreteUnsharedShadowNode = std::shared_ptr<ConcreteShadowNode>;
|
||||
@@ -88,19 +89,15 @@ class Element final {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets `state`.
|
||||
*/
|
||||
Element &state(SharedConcreteState state) {
|
||||
fragment_.state = state;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets `state` using callback.
|
||||
*/
|
||||
Element &state(std::function<SharedConcreteState()> callback) {
|
||||
fragment_.state = state();
|
||||
Element &stateData(std::function<void(ConcreteStateData&)> callback) {
|
||||
fragment_.stateCallback = [&]() -> StateData::Shared {
|
||||
auto stateData = ConcreteStateData();
|
||||
callback(stateData);
|
||||
return std::make_shared<ConcreteStateData>(stateData);
|
||||
};
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class ElementFragment final {
|
||||
using ReferenceCallback =
|
||||
std::function<void(ShadowNode::Unshared const &shadowNode)>;
|
||||
using FinalizeCallback = std::function<void(ShadowNode &shadowNode)>;
|
||||
using StateCallback = std::function<StateData::Shared()>;
|
||||
|
||||
/*
|
||||
* ComponentDescriptor part (describes the type)
|
||||
@@ -47,7 +48,6 @@ class ElementFragment final {
|
||||
* ShadowNode part (describes the instance)
|
||||
*/
|
||||
Props::Shared props;
|
||||
State::Shared state;
|
||||
List children;
|
||||
|
||||
/*
|
||||
@@ -55,6 +55,7 @@ class ElementFragment final {
|
||||
*/
|
||||
ReferenceCallback referenceCallback;
|
||||
FinalizeCallback finalizeCallback;
|
||||
StateCallback stateCallback;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
Reference in New Issue
Block a user