Combine react-native component with vue-native - react-native

Is there any way I could combine react native component like this one https://github.com/archriss/react-native-snap-carousel/tree/master/example with a vue native?
I have a project in vue-native and want to use react-native component inside it, but I have an erro I do not understand: The console says: Invariant Violation: expected a string (for built-in components) or a class/function (for composite components) but got: undefined
<template>
<nb-container>
<nb-content>
<carousel
:data="similarEventsData"
:renderItem="_renderItem"
:sliderWidth="sliderWidth"
:itemWidth="itemWidth"
:inactiveSlideScale="0.95"
:inactiveSlideOpacity="1"
:enableMomentum="true"
:activeSlideAlignment="'start'"
:containerCustomStyle="stylesObj.slider"
:contentContainerCustomStyle="stylesObj.sliderContentContainer"
:activeAnimationType="'spring'"
:activeAnimationOptions="{ friction: 4, tension: 40 }"
/>
</nb-content>
</nb-container>
</template>
<script>
import { Dimensions, Platform, Share } from "react-native";
import Carousel from 'react-native-snap-carousel';
import { scrollInterpolators, animatedStyles } from '../../utils/animations';
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
const slideHeight = viewportHeight * 0.36;
const slideWidth = wp(75);
const itemHorizontalMargin = wp(2);
export default {
components: { carousel: Carousel },
computed: {
similarEventsData () {
return [1, 2, 3]
}
},
data: function() {
return {
sliderWidth: viewportWidth,
itemWidth: slideWidth + itemHorizontalMargin * 2,
stylesObj: {
slider: {
marginTop: 15,
overflow: 'visible'
},
sliderContentContainer: {
paddingVertical: 10
},
}
};
},
methods: {
_renderItem ({item, index}) {
return <Text>fsd</Text>;
},
},
};
</script>
I expect to render a component but with no luck

this question is about 2 years old and I think in that time the devs added the functionality to do so, if somehow anyone is experiencing this question and ran into this post, here's what to do:
Example with Entypo icon pack from expo vector icons:
<script>
import { Entypo } from '#expo/vector-icons';
export default {
data(){
components: { Entype }
}
}
</script>
and then in template:
<template>
<entypo />
</template>

Related

React Native Paper - Redux ToolKit : Redux doesn't track change in fonts between different themes

I am building an application using React Native and Expo.
I'm using Redux ToolKit to store the state of different themes in React Native Paper. In this example, I switch between two themes (one light and one dark) with a simple switch. I can change the colors without any problem and I can see in the debugger that Redux follows perfectly the state changes between the two themes.
However, if I change the font size for only the light theme with the configureFonts function recommended by Paper, Redux (and so my application) does not follow the font size changes between the two themes.
Here is my redux slice (themeSlice.js):
import { createSlice, current } from '#reduxjs/toolkit'
import { MD3LightTheme, MD3DarkTheme, configureFonts } from 'react-native-paper';
const fontConfigLight = {
"labelLarge": {
"fontSize": 20,
"fontWeight": "500",
"letterSpacing": 0.1,
"lineHeight": 25,
}
};
const lightTheme = {
...MD3LightTheme,
fonts: configureFonts({config: fontConfigLight}),
};
const darkTheme = {
...MD3DarkTheme,
};
export const themeSlice = createSlice({
name: 'counter',
initialState: lightTheme,
reducers: {
switchTheme: (state, action) => {
if (action.payload === 'light'){
// console.log('light theme : labelLarge', current(state.fonts.labelLarge))
return lightTheme
} else {
// console.log('dark theme : labelLarge', current(state.fonts.labelLarge))
return darkTheme
}
},
}
})
export const { switchTheme } = themeSlice.actions
export default themeSlice.reducer
and I use the reducer in the SwitchPaper.js file :
import { useState } from 'react';
import { Switch } from 'react-native-paper';
import { useDispatch } from 'react-redux'
import { switchTheme } from './themeSlice'
const ThemeSwitch = () => {
const [isSwitchOn, setIsSwitchOn] = useState(false);
const dispatch = useDispatch()
const onToggleSwitch = () => {
setIsSwitchOn(!isSwitchOn)
if (isSwitchOn) {
dispatch(switchTheme('light'))
} else {
dispatch(switchTheme('dark'))
}
}
return (
<Switch value={isSwitchOn} onValueChange={onToggleSwitch} />
);
};
export default ThemeSwitch;
I suspect that the configureFonts function causes a conflict with the immutability of the Redux store as I sometimes get the error : TypeError: Cannot assign to read only property 'labelLarge' of object '#'.
I am looking for a solution to change fonts between themes while keeping my themes in the global Redux state.
EDIT:
a non-elegant way to solve the problem would be to change darkTheme to :
const darkTheme = {
...MD3DarkTheme,
myOwnProperty: true,
fonts: {
...MD3DarkTheme.fonts,
"labelLarge": {
fontFamily: "System",
letterSpacing: 0.5,
fontWeight: "500",
lineHeight: 16,
fontSize: 11
}
}
};
wishing that the function configureFonts was not there for a particular (and good) reason ...

Render children of ViroARImageMarker onAnchorFound

I'm currently working with the ViroReact Community Package in React Native to display a video in AR when a specific image is found. However the onTargetFound function of the ViroARImageMarker is not triggered, and the children of the ViroARImageMarker are not displayed.
When I added the onAnchorFound function to the ARScene (parent) the onAnchorFound method was triggered, however the children of the ViroARImageMarker still weren't rendered. Why is the function not triggered and therefore the children not displayed? How do I fix this?
The image is a 12x12cm black card with a bright orange logo (about 3cm) in the center. Neither of the targets are found in the ViroARImageMarker.
Here's my code:
Image Recognition Class
import React, { useEffect, useState } from 'react';
const {
ViroARScene,
ViroARImageMarker,
ViroARTrackingTargets,
ViroAnimations,
ViroVideo,
ViroMaterials,
ViroBox
} = require('#viro-community/react-viro');
const NewViroTracker = () => {
const videoPath = require('#assets/videos/wham.mp4');
const [videoAnimationName] = useState('showVideo');
const [playAnim, setPlayAnim] = useState(false);
function _onAnchorFound(evt: any) {
console.log('Anchor found in Marker :', evt);
setPlayAnim(true);
}
return (
<ViroARScene>
<ViroARImageMarker
target={'inviteCard'}
onAnchorFound={_onAnchorFound}>
<ViroVideo source={videoPath} />
</ViroARImageMarker>
<ViroARImageMarker
target={'logo'}>
<ViroBox position={[0, 0.25, 0]} scale={[0.5, 0.5, 0.5]} />
</ViroARImageMarker>
</ViroARScene>
);
};
ViroARTrackingTargets.createTargets({
inviteCard: {
source: require('#assets/images/invite-card.png'),
orientation: 'Up',
physicalWidth: 0.12 // real world width in meters
},
logo: {
source: require('#assets/images/logo-empty.png'),
orientation: 'Up',
physicalWidth: 0.0287 // real world width in meters
}
});
ViroMaterials.createMaterials({
chromaKeyFilteredVideo: {
chromaKeyFilteringColor: '#00FF00'
}
});
ViroAnimations.registerAnimations({
showVideo: {
properties: { scaleX: 1, scaleY: 1, scaleZ: 1 },
duration: 1000
},
closeVideo: {
properties: { scaleX: 0, scaleY: 0, scaleZ: 0 },
duration: 1
}
});
export default NewViroTracker;
App
import React from 'react';
const { ViroARSceneNavigator } = require('#viro-community/react-viro');
import styled from 'styled-components/native';
import NewViroTracker from 'components/NewViroTracker';
const App = () => {
return (
<ViroWrapper
autofocus={true}
initialScene={{
scene: NewViroTracker
}}
/>
);
};
export default App;
const ViroWrapper = styled(ViroARSceneNavigator)`
flex: 1;
`;
Dependencies:
"#viro-community/react-viro": "^2.21.1",
"react": "17.0.2",
"react-native": "0.66.3",

How can I pass the navigator prop from react-native-navigation v2 to my splash screen via Navigation.setRoot

I am trying to migrate from react-native-navigation v1 to react-native-navigation v2. I am struggling to move from
Navigation.startSingleScreenApp
to
Navigation.setRoot
When I switch from Navigation.startSingleScreenApp (v1) to Navigation.setRoot (v2), I no longer have the navigator prop that I was relying on to navigate around the application.
I have copy and pasted all relevant code below
RegisterScreens
import { Navigation } from 'react-native-navigation';
import SplashScreenScreen from './components/SplashScreen';
import { Provider } from 'react-redux';
import React from "react";
import SCREEN from './screenNames';
export default function registerScreens(store) {
Navigation.registerComponent(
SCREEN.SPLASH_SCREEN,
() => props => (<Provider store={store}><SplashScreenScreen {...props} /></Provider>), () => SplashScreenScreen);
App
import { Platform } from 'react-native';
import { Navigation } from 'react-native-navigation';
import registerScreens from './registerScreens';
import { Colors, Fonts } from './themes';
import { store } from './configureStore';
import NavigationListener from './NavigationEventListener';
import configureNotification from './configureNotification';
import SCREEN from './screenNames';
import Reactotron from 'reactotron-react-native';
const navBarTranslucent = Platform.OS === 'ios';
configureNotification();
registerScreens(store);
new NavigationListener(store);
const STARTING_SCREEN = SCREEN.SPLASH_SCREEN;
Navigation.events().registerAppLaunchedListener(() => {
Reactotron.log('5');
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
id: STARTING_SCREEN,
name: STARTING_SCREEN
}
}],
}
},
layout: {
orientation: 'portrait',
},
});
});
SplashScreen
import React from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { PersistGate } from 'redux-persist/es/integration/react';
import { navigateToFirstScreen } from '../redux/splash';
import { Colors, Fonts, Metrics } from '../themes';
import { persistor } from '../configureStore';
export class SplashScreen extends React.Component {
navigateTo = (screen) =>
this.props.navigator.push({
screen,
overrideBackPress: true,
backButtonHidden: true,
animated: false,
navigatorStyle: {
disabledBackGesture: true,
},
});
render() {
const { dispatchNavigateToFirstScreen } = this.props;
return (
<PersistGate
persistor={persistor}
onBeforeLift={() => setTimeout(() => dispatchNavigateToFirstScreen(this.navigateTo), 2000)}><View style={styles.bodyContainer}
>
<Text>Jono</Text>
</View>
</PersistGate>
);
}
}
const styles = StyleSheet.create({
bodyContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Colors.splashScreen,
},
appTitleText: {
fontSize: Fonts.size.splashScreenTitle,
fontFamily: Fonts.type.extraBold,
lineHeight: Metrics.lineHeight.appTitle,
textAlign: 'center',
color: Colors.textLightColor,
},
});
SplashScreen.propTypes = {
navigator: PropTypes.shape({
push: PropTypes.func.isRequired,
}).isRequired,
dispatchNavigateToFirstScreen: PropTypes.func.isRequired,
};
const mapDispatchToProps = (dispatch) => {
return {
dispatchNavigateToFirstScreen: (navigateTo) =>
dispatch(navigateToFirstScreen(navigateTo)),
};
};
export default connect(null, mapDispatchToProps)(SplashScreen);
I spent multiple hours trying to solve this problem so I am going to post my conclusion as an answer.
this.props.navigator is not used anymore in 2.x.
You need to use Navigation
This dude had the same problem and reached the same conclusion: https://github.com/wix/react-native-navigation/issues/3795

Attribute selectors in emotion

The following code customizes the google maps DrawingManager crosshair cursor. It works but I would like to be able to pass an svg cursor as a prop. I was trying to get it working using emotion but couldn't find anything similar in the emotion docs and my attempts failed. Can it be done in emotion?
Code: There are really only two relevant lines here (indicated) - the rest is given for context.
import React, { useEffect, useContext } from 'react'
import { GoogleMapContext, MapBox } from '#googlemap-react/core'
import ThemeSwitcher from './theme-switcher'
import styles from './styles/styles'
import './map.css' <--------------------------------------------------
export default function Map(props) {
const { state: { map } } = useContext(GoogleMapContext);
useEffect(() => map && map.setOptions({ draggableCursor: props.cursor }));
return <>
<MapBox
className='crosshair-cursor' <---------------------
apiKey={process.env.REACT_APP_GMAPS}
opts={{
center: { lat: -37.815018, lng: 144.946014 },
zoom: 11,
styles: styles[localStorage.getItem('mapTheme')],
}}
useDrawing
useGeometry
useGoogleApi
onClick={props.onClick}
onRightClick={props.onRightClick}
LoadingComponent={null}
/>
<ThemeSwitcher bindingPosition='TOP_LEFT' map={map} />
{props.children}
</>
}
map.css:
.crosshair-cursor [style*='crosshair'] {
cursor: url("https://i.stack.imgur.com/mA4e2.jpg?s=48&g=1")24 24, crosshair !important;
}
My attempt:
import React, { useEffect, useContext } from 'react'
import { GoogleMapContext, MapBox } from '#googlemap-react/core'
import ThemeSwitcher from './theme-switcher'
import styles from './styles/styles'
import './map.css'
import {css} from '#emotion/core'
const cursor = css`[style*='crosshair'] {
cursor: url("https://i.stack.imgur.com/mA4e2.jpg?s=48&g=1")24 24, crosshair !important;
}`
export default function Map(props) {
const { state: { map } } = useContext(GoogleMapContext);
useEffect(() => map && map.setOptions({ draggableCursor: props.cursor }));
return <>
<MapBox
// className='crosshair-cursor'
css={cursor}
apiKey={process.env.REACT_APP_GMAPS}
opts={{
center: { lat: -37.815018, lng: 144.946014 },
zoom: 11,
styles: styles[localStorage.getItem('mapTheme')],
}}
useDrawing
useGeometry
useGoogleApi
onClick={props.onClick}
onRightClick={props.onRightClick}
LoadingComponent={null}
/>
<ThemeSwitcher bindingPosition='TOP_LEFT' map={map} />
{props.children}
</>
}

test with enzyme a react component with context: return an empty object

I'm trying to execute a dummy test with enzyme over a component. the test is about to check the context. even though I'm writing the same code as enzyme's documentation the context is always empty.
import React from 'react';
import { shallow } from 'enzyme';
import Overlay from '../../../../app/components/Overlay/Overlay';
describe('<Overlay />', () => {
it.only('return a context', () => {
const wrapper = shallow(<Overlay />, { context: { foo: 10 } });
console.log(wrapper.context());
// expect(wrapper.context().foo).to.equal(10);
});
})
the test's output is:
<Overlay />
{}
✓ return a context
where am I wrong?
Since the details of Overlay component is not given, I assume the context is not used in it (pls check childContextTypes and getChildContext are defined properly)
For example, refer the explanation for contexts in react documents
I have taken the same example to enable the test,
import React from 'react';
export default class Button extends React.Component {
render() {
return (
<button style={{ background: this.context.color }}>
{this.props.children}
</button>
);
}
}
Button.contextTypes = {
color: React.PropTypes.string,
};
class Message extends React.Component {
render() {
return (
<div>
{this.props.text} <Button>Delete</Button>
</div>
);
}
}
class MessageList extends React.Component {
getChildContext() {
return { color: 'purple' };
}
render() {
const children = this.props.messages.map((message) =>
<Message text={message.text} />
);
return <div>{children}</div>;
}
}
MessageList.childContextTypes = {
color: React.PropTypes.string,
};
I've created the test for Button component as below,
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import Button from '../../src/components/SampleComp';
describe.only('<Button />', () => {
it('assert for context', () => {
const wrapper = shallow(
<Button />,
{ context: { color: 'red' } }
);
expect(wrapper.context().color).to.equal('red');
expect(wrapper.context('color')).to.equal('red');
});
});
<Button />
✓ assert for context
1 passing (214ms)
This will assert it correctly.