mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Pass State to preallocateView and createView methods whenever possible
Summary: For some components, we will have state as soon as the ShadowNode is created that may be meaningful. In those cases, ViewManagers should be able to use State to create or preallocate views. FB: This will be used in following diffs for Litho support. Reviewed By: mdvacca Differential Revision: D15343702 fbshipit-source-id: 8fd672251cb88dea662b5cae5a9efc96877d28a9
This commit is contained in:
committed by
Facebook Github Bot
parent
c9df1db00a
commit
b05761f1bb
@@ -176,6 +176,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
int reactTag,
|
||||
final String componentName,
|
||||
@Nullable ReadableMap props,
|
||||
Object stateWrapper,
|
||||
boolean isLayoutable) {
|
||||
ThemedReactContext context = mReactContextForRootTag.get(rootTag);
|
||||
String component = getFabricComponentName(componentName);
|
||||
@@ -187,6 +188,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
reactTag,
|
||||
component,
|
||||
props,
|
||||
(StateWrapper) stateWrapper,
|
||||
isLayoutable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,14 +290,17 @@ local_ref<JMountItem::javaobject> createUpdateStateMountItem(
|
||||
// Do not hold onto Java object from C
|
||||
// We DO want to hold onto C object from Java, since we don't know the
|
||||
// lifetime of the Java object
|
||||
auto javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = state;
|
||||
local_ref<StateWrapperImpl::JavaPart> javaStateWrapper = nullptr;
|
||||
if (state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = state;
|
||||
}
|
||||
|
||||
return updateStateInstruction(
|
||||
javaUIManager,
|
||||
mutation.newChildShadowView.tag,
|
||||
javaStateWrapper.get());
|
||||
(javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr));
|
||||
}
|
||||
|
||||
|
||||
@@ -525,13 +528,23 @@ void Binding::schedulerDidRequestPreliminaryViewAllocation(
|
||||
|
||||
static auto preallocateView =
|
||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||
->getMethod<void(jint, jint, jstring, ReadableMap::javaobject, jboolean)>("preallocateView");
|
||||
->getMethod<void(jint, jint, jstring, ReadableMap::javaobject, jobject, jboolean)>("preallocateView");
|
||||
|
||||
local_ref<ReadableMap::javaobject> readableMap =
|
||||
// Do not hold onto Java object from C
|
||||
// We DO want to hold onto C object from Java, since we don't know the
|
||||
// lifetime of the Java object
|
||||
local_ref<StateWrapperImpl::JavaPart> javaStateWrapper = nullptr;
|
||||
if (shadowView.state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = shadowView.state;
|
||||
}
|
||||
|
||||
local_ref<ReadableMap::javaobject> props =
|
||||
castReadableMap(ReadableNativeMap::newObjectCxxArgs(shadowView.props->rawProps));
|
||||
auto component = getPlatformComponentName(shadowView);
|
||||
preallocateView(
|
||||
javaUIManager_, surfaceId, shadowView.tag, component.get(), readableMap.get(), isLayoutableShadowNode);
|
||||
javaUIManager_, surfaceId, shadowView.tag, component.get(), props.get(), (javaStateWrapper != nullptr ? javaStateWrapper.get() : nullptr), isLayoutableShadowNode);
|
||||
}
|
||||
|
||||
void Binding::registerNatives() {
|
||||
|
||||
+4
-3
@@ -9,6 +9,7 @@ package com.facebook.react.fabric.mounting;
|
||||
import android.view.View;
|
||||
import androidx.annotation.UiThread;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import java.util.WeakHashMap;
|
||||
@@ -26,13 +27,13 @@ public final class ContextBasedViewPool implements ViewFactory {
|
||||
|
||||
@UiThread
|
||||
void createView(ThemedReactContext context, ReactStylesDiffMap props, String componentName) {
|
||||
getViewPool(context).createView(componentName, props, context);
|
||||
getViewPool(context).createView(componentName, props, null, context);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@Override
|
||||
public View getOrCreateView(String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
|
||||
return getViewPool(context).getOrCreateView(componentName, props, context);
|
||||
public View getOrCreateView(String componentName, ReactStylesDiffMap props, StateWrapper stateWrapper, ThemedReactContext context) {
|
||||
return getViewPool(context).getOrCreateView(componentName, props, stateWrapper, context);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
||||
+13
-10
@@ -170,11 +170,12 @@ public class MountingManager {
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void createViewWithProps(
|
||||
public void createView(
|
||||
ThemedReactContext themedReactContext,
|
||||
String componentName,
|
||||
int reactTag,
|
||||
@Nullable ReadableMap props,
|
||||
@Nullable StateWrapper stateWrapper,
|
||||
boolean isLayoutable) {
|
||||
if (mTagToViewState.get(reactTag) != null) {
|
||||
return;
|
||||
@@ -183,19 +184,20 @@ public class MountingManager {
|
||||
View view = null;
|
||||
ViewManager viewManager = null;
|
||||
|
||||
ReactStylesDiffMap diffMap = null;
|
||||
ReactStylesDiffMap propsDiffMap = null;
|
||||
if (props != null) {
|
||||
diffMap = new ReactStylesDiffMap(props);
|
||||
propsDiffMap = new ReactStylesDiffMap(props);
|
||||
}
|
||||
|
||||
if (isLayoutable) {
|
||||
viewManager = mViewManagerRegistry.get(componentName);
|
||||
view = mViewFactory.getOrCreateView(componentName, diffMap, themedReactContext);
|
||||
view = mViewFactory.getOrCreateView(componentName, propsDiffMap, stateWrapper, themedReactContext);
|
||||
view.setId(reactTag);
|
||||
}
|
||||
|
||||
ViewState viewState = new ViewState(reactTag, view, viewManager);
|
||||
viewState.mCurrentProps = diffMap;
|
||||
viewState.mCurrentProps = propsDiffMap;
|
||||
viewState.mCurrentState = (stateWrapper != null ? stateWrapper.getState() : null);
|
||||
|
||||
mTagToViewState.put(reactTag, viewState);
|
||||
}
|
||||
@@ -313,6 +315,7 @@ public class MountingManager {
|
||||
String componentName,
|
||||
int reactTag,
|
||||
@Nullable ReadableMap props,
|
||||
@Nullable StateWrapper stateWrapper,
|
||||
boolean isLayoutable) {
|
||||
|
||||
if (mTagToViewState.get(reactTag) != null) {
|
||||
@@ -320,7 +323,7 @@ public class MountingManager {
|
||||
"View for component " + componentName + " with tag " + reactTag + " already exists.");
|
||||
}
|
||||
|
||||
createViewWithProps(reactContext, componentName, reactTag, props, isLayoutable);
|
||||
createView(reactContext, componentName, reactTag, props, stateWrapper, isLayoutable);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -362,10 +365,10 @@ public class MountingManager {
|
||||
final int mReactTag;
|
||||
final boolean mIsRoot;
|
||||
@Nullable final ViewManager mViewManager;
|
||||
public ReactStylesDiffMap mCurrentProps;
|
||||
public ReadableMap mCurrentLocalData;
|
||||
public ReadableMap mCurrentState;
|
||||
public EventEmitterWrapper mEventEmitter;
|
||||
public ReactStylesDiffMap mCurrentProps = null;
|
||||
public ReadableMap mCurrentLocalData = null;
|
||||
public ReadableMap mCurrentState = null;
|
||||
public EventEmitterWrapper mEventEmitter = null;
|
||||
|
||||
private ViewState(int reactTag, @Nullable View view, @Nullable ViewManager viewManager) {
|
||||
this(reactTag, view, viewManager, false);
|
||||
|
||||
@@ -8,11 +8,13 @@ package com.facebook.react.fabric.mounting;
|
||||
|
||||
import android.view.View;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface ViewFactory {
|
||||
|
||||
View getOrCreateView(String componentName, ReactStylesDiffMap props, ThemedReactContext context);
|
||||
View getOrCreateView(String componentName, @Nullable ReactStylesDiffMap props, @Nullable StateWrapper stateWrapper, ThemedReactContext context);
|
||||
|
||||
void recycle(ThemedReactContext context, String componentName, View view);
|
||||
|
||||
|
||||
+4
-2
@@ -9,8 +9,10 @@ package com.facebook.react.fabric.mounting;
|
||||
import androidx.annotation.UiThread;
|
||||
import android.view.View;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ViewManagerFactory implements ViewFactory {
|
||||
|
||||
@@ -23,8 +25,8 @@ public class ViewManagerFactory implements ViewFactory {
|
||||
@UiThread
|
||||
@Override
|
||||
public View getOrCreateView(
|
||||
String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
|
||||
return mViewManagerRegistry.get(componentName).createViewWithProps(context, props, null);
|
||||
String componentName, @Nullable ReactStylesDiffMap props, @Nullable StateWrapper stateWrapper, ThemedReactContext context) {
|
||||
return mViewManagerRegistry.get(componentName).createView(context, props, stateWrapper, null);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.annotation.UiThread;
|
||||
import android.view.View;
|
||||
import com.facebook.react.common.ClearableSynchronizedPool;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
@@ -26,20 +27,20 @@ public final class ViewPool {
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void createView(String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
|
||||
void createView(String componentName, ReactStylesDiffMap props, StateWrapper stateWrapper, ThemedReactContext context) {
|
||||
ClearableSynchronizedPool<View> viewPool = getViewPoolForComponent(componentName);
|
||||
ViewManager viewManager = mViewManagerRegistry.get(componentName);
|
||||
// TODO: T31905686 Integrate / re-implement jsResponder
|
||||
View view = viewManager.createViewWithProps(context, props, null);
|
||||
View view = viewManager.createView(context, props, stateWrapper, null);
|
||||
viewPool.release(view);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
View getOrCreateView(String componentName, ReactStylesDiffMap props, ThemedReactContext context) {
|
||||
View getOrCreateView(String componentName, ReactStylesDiffMap props, StateWrapper stateWrapper, ThemedReactContext context) {
|
||||
ClearableSynchronizedPool<View> viewPool = getViewPoolForComponent(componentName);
|
||||
View view = viewPool.acquire();
|
||||
if (view == null) {
|
||||
createView(componentName, props, context);
|
||||
createView(componentName, props, stateWrapper, context);
|
||||
view = viewPool.acquire();
|
||||
}
|
||||
return view;
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ public class CreateMountItem implements MountItem {
|
||||
|
||||
@Override
|
||||
public void execute(MountingManager mountingManager) {
|
||||
mountingManager.createViewWithProps(mContext, mComponent, mReactTag, null, mIsLayoutable);
|
||||
mountingManager.createView(mContext, mComponent, mReactTag, null, null, mIsLayoutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-1
@@ -13,6 +13,7 @@ import androidx.annotation.Nullable;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.fabric.mounting.MountingManager;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
|
||||
/** {@link MountItem} that is used to pre-allocate views for JS components. */
|
||||
@@ -22,6 +23,7 @@ public class PreAllocateViewMountItem implements MountItem {
|
||||
private final int mRootTag;
|
||||
private final int mReactTag;
|
||||
private final @Nullable ReadableMap mProps;
|
||||
private final @Nullable StateWrapper mStateWrapper;
|
||||
private final ThemedReactContext mContext;
|
||||
private final boolean mIsLayoutable;
|
||||
|
||||
@@ -31,11 +33,13 @@ public class PreAllocateViewMountItem implements MountItem {
|
||||
int reactTag,
|
||||
String component,
|
||||
@Nullable ReadableMap props,
|
||||
StateWrapper stateWrapper,
|
||||
boolean isLayoutable) {
|
||||
mContext = context;
|
||||
mComponent = component;
|
||||
mRootTag = rootTag;
|
||||
mProps = props;
|
||||
mStateWrapper = stateWrapper;
|
||||
mReactTag = reactTag;
|
||||
mIsLayoutable = isLayoutable;
|
||||
}
|
||||
@@ -45,7 +49,7 @@ public class PreAllocateViewMountItem implements MountItem {
|
||||
if (DEBUG) {
|
||||
FLog.d(TAG, "Executing pre-allocation of: " + toString());
|
||||
}
|
||||
mountingManager.preallocateView(mContext, mComponent, mReactTag, mProps, mIsLayoutable);
|
||||
mountingManager.preallocateView(mContext, mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-3
@@ -8,7 +8,6 @@
|
||||
package com.facebook.react.uimanager;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -19,7 +18,6 @@ import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.PopupMenu;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.R;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
@@ -256,7 +254,7 @@ public class NativeViewHierarchyManager {
|
||||
try {
|
||||
ViewManager viewManager = mViewManagers.get(className);
|
||||
|
||||
View view = viewManager.createViewWithProps(themedContext, null, mJSResponderHandler);
|
||||
View view = viewManager.createView(themedContext, null, null, mJSResponderHandler);
|
||||
mTagsToViews.put(tag, view);
|
||||
mTagsToViewManagers.put(tag, viewManager);
|
||||
|
||||
|
||||
@@ -11,10 +11,8 @@ import android.content.Context;
|
||||
import android.view.View;
|
||||
import com.facebook.react.bridge.BaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.touch.JSResponderHandler;
|
||||
import com.facebook.react.touch.ReactInterceptingViewGroup;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
@@ -41,6 +39,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
*
|
||||
* @param viewToUpdate
|
||||
* @param props
|
||||
* @param stateWrapper
|
||||
*/
|
||||
public void updateProperties(@Nonnull T viewToUpdate, ReactStylesDiffMap props) {
|
||||
ViewManagerPropertyUpdater.updateProps(this, viewToUpdate, props);
|
||||
@@ -53,17 +52,18 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
private final @Nonnull T createView(
|
||||
@Nonnull ThemedReactContext reactContext,
|
||||
JSResponderHandler jsResponderHandler) {
|
||||
return this.createViewWithProps(reactContext, null, jsResponderHandler);
|
||||
return createView(reactContext, null, null, jsResponderHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a view with knowledge of props.
|
||||
*/
|
||||
public @Nonnull T createViewWithProps(
|
||||
public @Nonnull T createView(
|
||||
@Nonnull ThemedReactContext reactContext,
|
||||
ReactStylesDiffMap props,
|
||||
@Nullable ReactStylesDiffMap props,
|
||||
@Nullable StateWrapper stateWrapper,
|
||||
JSResponderHandler jsResponderHandler) {
|
||||
T view = createViewInstanceWithProps(reactContext, props);
|
||||
T view = createViewInstance(reactContext, props, stateWrapper);
|
||||
addEventEmitters(reactContext, view);
|
||||
if (view instanceof ReactInterceptingViewGroup) {
|
||||
((ReactInterceptingViewGroup) view).setOnInterceptTouchEventListener(jsResponderHandler);
|
||||
@@ -115,7 +115,7 @@ public abstract class ViewManager<T extends View, C extends ReactShadowNode>
|
||||
* Override it if you need props upon creation of the view.
|
||||
* @param reactContext
|
||||
*/
|
||||
protected @Nonnull T createViewInstanceWithProps(@Nonnull ThemedReactContext reactContext, ReactStylesDiffMap initialProps) {
|
||||
protected @Nonnull T createViewInstance(@Nonnull ThemedReactContext reactContext, @Nullable ReactStylesDiffMap initialProps, @Nullable StateWrapper stateWrapper) {
|
||||
T view = createViewInstance(reactContext);
|
||||
if (initialProps != null) {
|
||||
updateProperties(view, initialProps);
|
||||
|
||||
Reference in New Issue
Block a user