How are image props handled? #31
-
I've started updating my navigation library to the new architecture on iOS. I'm working on the <BarButton image={require('./home.png')} /> In the old architecture on iOS I'd map this to a RCT_EXPORT_VIEW_PROPERTY(image, UIImage)
- (void)setImage:(UIImage *)image
{
self.button.image = image;
} What's the way to do this in the new architecture on iOS? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 13 replies
-
Hi @grahammendick, thanks for your question. In the New Architecture, we still need this snippet in the Native Component. RCT_EXPORT_VIEW_PROPERTY(image, UIImage) Then, in the Fabric Component, we have to implement the following method: - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps An example on how to do that can be found here at step 5. The likely implementation, but please test it, will be something like: - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &oldViewProps = *std::static_pointer_cast<BarButtonProps const>(_props);
const auto &newViewProps = *std::static_pointer_cast<BarButtonProps const>(props);
if (oldViewProps.image != newViewProps.image) {
_view.button.image = newViewProps.image;
}
[super updateProps:props oldProps:oldProps];
} Let me know if it works or if you had any other issue! |
Beta Was this translation helpful? Give feedback.
-
Hi @grahammendick! First of all, infinite thanks for your patience. It has been a busy period and I also had to reach out to different people to have a precise answer for your case. We can suggest 3 different ways to approach the solution. JS Based ApproachLet's start with saying that the ideal usage for React Native is to try to minimize the amount of native code, to share as much as JS as possible. Starting from this idea, the best and suggested approach to develop a component like the Custom ImageLoaderThe second approach by simplicity, is to create an
PRO:
CON:
Write Your Own StateRemember that the CodeGen is just a tool we created to simplify the 90% of the use cases. You don't have to use it if your use case is not well supported and, unfortunately, that is one of these cases. What does that means?
Once we have these elements, we can create our own We agree that this is not the best possible Dev X. We have plan to improve the Dev X and the codegen in the future, but we don't have a roadmap yet. It follows the code of an example I created to verify that everything works. Note: It's possible to partially leverage the codegen to get the scaffolding for many files. JS SpecAs always, the first step is to declare some JS specifications that we can leverage. // @flow
import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
import type {HostComponent} from 'react-native';
import { ViewStyle } from 'react-native';
import type {ImageSource} from '../../Image/ImageSource';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
type NativeProps = $ReadOnly<{|
...ViewProps,
color: string,
image?: ?ImageSource,
|}>;
export default (codegenNativeComponent<NativeProps>(
'ColoredView',
): HostComponent<NativeProps>); After that, we Have to create all the files that the codegen usually creates for us. We will have to update some of them, so the suggestion is to:
So... Let's start:
|
Beta Was this translation helpful? Give feedback.
-
I’ve spent weeks working out how to use c++/rendered state in Fabric. I don’t understand why React Native couldn’t write this up. It seems needlessly cruel of them. I initially took the 'Write You Own State' section above to be React Native’s answer on how to use c++ state. But there are mistakes and omissions. So I’m going to save other people the pain by writing up what I learnt. The key omission from the 'Write You Own State' section above is it doesn’t mention the export default (codegenNativeComponent<NativeProps>(
'NVBarButton',
{interfaceOnly: true}
): HostComponent<NativeProps>); This simplifies the 'Write You Own State' section because there are now only five classes to hand-write. These can be copied either from React Native repo or from the 'Write You Own State' section above.
The next omission is that these files must be included as source files in the podspec for them to make it into the iOS build. So add them to a ‘cpp’ folder, for example, and then add that to the
You can see all these changes in my PR that adds image props to the Another omission is how to get Android working with these changes. Even though c++ state isn’t needed on Android (image props are handled differently), Android won’t build without these hand-written files. The following changes need to be made by the user of your library in their app. In the Android.mk of the app LOCAL_C_INCLUDES := $(LOCAL_PATH) $(NODE_MODULES_DIR)/navigation-react-native/cpp
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(NODE_MODULES_DIR)/navigation-react-native/cpp/*.cpp)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) And include libreact_render_mapbuffer \
libreact_render_imagemanager \ In MainComponentsRegistry.cpp of the app #include <NVBarButtonComponentDescriptor.h> |
Beta Was this translation helpful? Give feedback.
I’ve spent weeks working out how to use c++/rendered state in Fabric. I don’t understand why React Native couldn’t write this up. It seems needlessly cruel of them. I initially took the 'Write You Own State' section above to be React Native’s answer on how to use c++ state. But there are mistakes and omissions. So I’m going to save other people the pain by writing up what I learnt.
The key omission from the 'Write You Own State' section above is it doesn’t mention the
interfaceOnly
property of the NativeComponent spec. When you include this then React Native doesn’t codegen everything. It still codegens the Props and EventEmitters, for example, but it doesn’t codegen the ComponentDescript…