For some reason none of the questions or online videos online is helping me solve my issue. This is my code below and its still displaying my page without an image. If anyone can help me see whats wrong that would be great.
import { Image, Text } from 'react-native';
import React, { Component } from 'react';
class BackgroundImage {
render() {
return (
<Image source={require('../../images/showcase.jpg')} style=
{styles.backgroundImage}>
{this.props.children}
</Image>
);
}
}
class TestBackgroundImage extends Component {
render() {
return (
<BackgroundImage>
<Text style={styles.text}>Fullscreen!</Text>
</BackgroundImage>
);
}
}
const styles = StyleSheet.create({
backgroundImage: {
flex: 1,
width: 50,
height: 50,
resizeMode: 'cover'
},
text: {
textAlign: 'center',
color: 'white',
backgroundColor: 'rgba(0,0,0,0)',
fontSize: 32
}
});
const Home = () => (
<div>
<h2>Home page</h2>
</div>
);
export default Home;
This might be because you are setting width and height null. height and width must have value, otherwise image doesn't shows. Please try to assign value of height and width e.g.
backgroundImage: {
flex: 1,
width: 50,
height: 50,
resizeMode: 'cover'
},
Have you tried to import the Image component in BackGroundImage and BackGroundImage in TestBackgroundImage?
// In BackGroundImage.js
import Image from 'path';
// In TestBackgroundImage.js
import BackGroundImage from 'path';
and I think, you want to show all components in Home component.
so
//import all components in Home.js
const Home = ()=> {
return {
<BackgroundImage/>
<TestBackgroundImage/>
}
}
Instead of using image use ImageBackGround directly
class BackgroundImage {
render() {
return (
<ImageBackground source={require('../../images/showcase.jpg')} style=
{styles.backgroundImage}>
{this.props.children}
</ImageBackground>
);
}
}
Related
I want to test a basic component name TitleHeader which uses HStack and VStack from native base.
The component:-
import {Center, HStack, VStack} from 'native-base';
import React from 'react';
import {View, Text} from 'react-native';
import appColors from '../../constants/appColors';
//Icon Imports
import Ionicons from 'react-native-vector-icons/Ionicons';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useNavigation} from '#react-navigation/core';
const TitleHeader = ({
title = 'Header Title',
navigationBack = false,
center = false,
onBackPress,
drawer = false,
style = {},
}) => {
console.log(title);
const navigation = useNavigation();
const handleGoBack = () => {
if (onBackPress && typeof onBackPress === 'function') {
onBackPress();
} else if (drawer) {
navigation.goBack();
} else {
navigation.pop();
}
};
return (
<HStack
bg={appColors.primaryBlue}
style={[
{
height: 55,
position: 'relative',
},
style,
]}
alignItems="center"
px={3}>
{navigationBack ? (
<View style={{position: 'absolute', zIndex: 10, left: 10}}>
<TouchableOpacity
onPress={handleGoBack}
style={{
width: 35,
height: 35,
justifyContent: 'center',
alignItems: 'center',
}}>
<Ionicons name="arrow-back" size={26} color="white" />
</TouchableOpacity>
</View>
) : null}
<VStack flex={1} alignItems="center" pl={2}>
<Text
color="white"
fontSize="lg"
numberOfLines={1}
ellipsizeMode="tail"
style={
center
? {}
: {
width: '80%',
}
}>
{title}
</Text>
</VStack>
</HStack>
);
};
export default TitleHeader;
Following is my test case which uses jest for testing:-
import React from 'react';
import {render} from '#testing-library/react-native';
import TitleHeader from '../src/components/AppHeaders/TitleHeader';
import renderer from 'react-test-renderer';
import {NavigationContainer} from '#react-navigation/native';
import {NativeBaseProvider} from 'native-base';
jest.mock('native-base');
const wrapper = ({children}) => (
<NativeBaseProvider
initialWindowMetrics={{
frame: {x: 0, y: 0, width: 0, height: 0},
insets: {top: 0, left: 0, right: 0, bottom: 0},
}}>
{children}
</NativeBaseProvider>
);
describe('Testing Title Header for screens', () => {
test('should render title header', () => {
const tree = renderer
.create(
<NavigationContainer>
<TitleHeader title={'HEADER TEST'} />
</NavigationContainer>,
{wrapper},
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
But I am getting this error inspite of using jest.mock('native-base') in my jest.setup.js.
I am new to testing please help me render this component first and test it using jest. Also, one more thing to add is that if I do not use the wrapper function it throws error telling me that "theme is not defined. Did you forget to wrap your app inside NativeBaseProvider?".
If the component that you trying to test has the theme coming from NativeBase you need to provide the <ThemeProvider/> (Spelling might differ depending on the library, in your case <NativeBaseProvider/>
If you do jest.mock('native-base') and you do not return anything will cause Nothing was returned from render error.
Did you add native-base library to transformIgnorePatterns of jest.config as suggested in this issue?
I just started learning React Native and I am having a tough time rendering a video in my app. Basically whats happening is that the same stylesheet that I have used for other parts of my code works for everything except when I use it for my video. I have no idea why that is....
Here is what I have done to solve this error:
So Change the import line
import { LoginPageStyle } from "../StyleSheet/LoginPageStyle";
To
import LoginPageStyle from "../StyleSheet/LoginPageStyle";
and I have also tried..
Make it as named export inside LoginPageStyle
export default LoginPageStyle;
To
export { LoginPageStyle };
This is my main code for the component
import React, { Component } from "react";
import { Button, StyleSheet, View, Text } from "react-native";
import LoginButton from "./LoginButton";
import { LoginPageStyle } from "../StyleSheet/LoginPageStyle";
import Video from "react-native-video";
export class LoginPage extends Component {
super(props) {
this.alertUser = this.alertUser.bind(this);
}
connectViaFacebook = () => {
alert("Connecting To Facebook");
};
connectViaPhoneNumber = () => {
alert("Connecting via phone number");
};
render() {
return (
<View>
<Video
source={require("../Graphics/LoginVideo.mp4")}
style={LoginPageStyle.backgroundVideo}
muted={true}
repeat={true}
resizeMode={"cover"}
rate={1.0}
ignoreSilentSwitch={"obey"}
/>
/> <Text style={LoginPageStyle.title}>Let's Hang</Text>
<Text>Where people go on adventures</Text>
<View style={LoginPageStyle.bottom}>
<LoginButton
text="Connect with Phone Number"
onPress={this.connectViaPhoneNumber}
color="#d10047"
/>
<LoginButton
text="Connect with Facebook"
onPress={this.connectViaFacebook}
color="#3B5998"
/>
</View>
</View>
);
}
}
export default LoginPage;
And here is my style sheet...
import { StyleSheet, Dimensions } from "react-native";
const { width, height } = Dimensions.get("window");
const LoginPageStyle = StyleSheet.create({
title: {
color: "green",
fontSize: 60,
alignItems: "center",
justifyContent: "center",
marginTop: 60,
},
bottom: {
paddingTop: 450,
},
backgroundVideo: {
height: height,
position: "absolute",
top: 0,
left: 0,
alignItems: "stretch",
bottom: 0,
right: 0,
},
});
export default LoginPageStyle;
1) If you are using this import
import { LoginPageStyle } from "../StyleSheet/LoginPageStyle";
then export should look like this :
export { LoginPageStyle };
2) And if this import :
import LoginPageStyle from "../StyleSheet/LoginPageStyle";
Then this export :
export default LoginPageStyle;
And what you are using is :
import { LoginPageStyle } from "../StyleSheet/LoginPageStyle";
export default LoginPageStyle;
How can I make a transition with maxHeight in React Native?
The equivalent code in React would be
function App() {
const [isOpen, setIsOpen] = useState(false)
return (
<div className="App">
<div className={`collapsible ${isOpen ? 'opened' : ''}`}>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? 'Close' : 'Open'}
</button>
</div>
);
}
And the css
.collapsible {
max-height: 0;
transition: max-height 0.35s ease-out;
overflow: hidden;
}
.opened {
max-height: 200px;
}
Here is a working codesandbox
How can I make the same but in React Native?
My guess is that you want to persist the animation when "opening" the view.
This is not supported out of the box using a StyleSheet object in React Native. You will have to implement this yourself using the Animated API.
https://facebook.github.io/react-native/docs/animations
Example:
import React from "react"
import { Animated } from "react-native"
import { Text, StyleSheet, TextProps } from "react-native"
import { TouchableOpacity } from "react-native-gesture-handler"
class AnimatedComponent {
constructor(props){
super(props)
this.state = { open: false }
this.animatedHeightValue = new Animated.Value(0)
}
_triggerAnimation = () => {
Animated.timing(this.animatedHeightValue, {
toValue: this.state.open ? 0 : 200,
duration: 200
}).start(() => {
this.setState({open: !this.state.open})
})
}
render() {
return(
<View>
<Animated.View style={{height: this.animatedHeightValue, backgroundColor: "blue"}}>
<Text>
{"Hello world"}
</Text>
</Animated.View>
<TouchableOpacity onPress={this._triggerAnimation}>
<Text>
{"Press for magic"}
</Text>
</TouchableOpacity>
</View>
)
}
Indentation is awful sorry, but should give an idea.
Hmmm.. I'm not completely sure did you actually meant this. But in case we're on the same page, check my Snack at: https://snack.expo.dev/#zvona/maxheight-animation
Here is the actual code (in case link of the snack gets deprecated):
import React, { useState, useRef } from 'react';
import {
Animated,
Text,
TouchableOpacity,
View,
StyleSheet,
} from 'react-native';
const App = () => {
const [isOpen, setIsOpen] = useState(false);
const [contentStyle, setContentStyle] = useState({ visibility: 'hidden' });
const currentHeight = useRef(new Animated.Value(0)).current;
const [maxHeight, setMaxHeight] = useState(0);
const toggleContent = () => {
setIsOpen(!isOpen);
Animated.timing(currentHeight, {
toValue: isOpen ? 0 : maxHeight,
duration: 350,
}).start();
};
const getContentHeight = ({ nativeEvent }) => {
if (maxHeight !== 0) {
return;
}
const { height } = nativeEvent.layout;
setMaxHeight(height);
setContentStyle({visibility: 'visible', height: currentHeight });
};
return (
<View style={styles.container}>
<TouchableOpacity onPress={toggleContent} style={styles.button}>
<Text>{'Open'}</Text>
</TouchableOpacity>
<Animated.View
style={[styles.content, contentStyle]}
onLayout={getContentHeight}>
<Text style={styles.paragraph}>
Change code in the editor and watch it change on your phone! Save to
get a shareable url.
</Text>
</Animated.View>
</View>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
backgroundColor: '#ffffff',
padding: 8,
},
button: {
justifyContent: 'center',
alignItems: 'center',
width: 120,
borderWidth: 1,
borderColor: 'black',
backgroundColor: '#c0c0c8',
padding: 10,
},
content: {
borderWidth: 1,
borderColor: 'blue',
overflow: 'hidden',
},
paragraph: {
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
export default App;
The key ingredient of detecting the maxHeight is in onLayout event of the Animated.View. Then some magic on displaying content through state handling.
And if you want to define maxHeight manually, then just rip the getContentHeight off.
I am trying to render logout button and its rendering it but its not showing height for the button. i am also adding the files which have data for Both button.js and app.js. now the problem is its showind button but the height of the button is 1 dont know why. i copied this code from somewhere and trying to make something out of it. some other place i am easily able to use button width. but not here.
and my common/index.js has all exported files like Button.js and all
getting button in this form.its showing but not with the size
Button.js
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
const Button = ({ onPress, children }) => {
const { buttonStyle, textStyle } = styles;
return (
<TouchableOpacity onPress={onPress} style={buttonStyle}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
);
};
const styles = {
textStyle: {
alignSelf: 'center',
color: '#007aff',
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10
},
buttonStyle: {
flex: 1,
alignSelf: 'stretch',
backgroundColor: '#fff',
borderRadius: 5,
borderWidth: 1,
borderColor: '#007aff',
marginLeft: 5,
marginRight: 5
}
};
export { Button };
App.js
import React, {Component} from 'react';
import { View } from 'react-native';
import firebase from 'firebase';
import { Header, Button, Spinner, Card } from './components/common';
import LoginForm from './components/LoginForm';
class App extends Component {
state = { loggedIn: null };
componentWillMount() {
firebase.initializeApp({
apiKey: '***********************************',
authDomain: '*********************************',
databaseURL: '***********************************',
projectId: '***************************************',
storageBucket: '*************************************',
messagingSenderId: '32810678085'
});
firebase.auth().onAuthStateChanged((user) => {
if(user){
this.setState({ loggedIn: true });
}else {
this.setState({ loggedIn: false });
}
});
}
renderContent(){
switch (this.state.loggedIn){
case true:
return <Button> Log out </Button>
case false:
return <LoginForm />;
default:
return <Spinner size="large" />;
}
}
render() {
return (
<View>
<Header headerText="Authentication" />
{this.renderContent()}
</View>
)
}
}
export default App;
I've had the exact same problem.
First of all, the version of React Native in the tutorial was different to the version that you used judging by the date of the post, this could point to a possible explanation of why the code worked in the tutorial but not in our code, although I can't know.
On the other side, it's not exactly true that the button code works in other
parts of the code.
When you render the login form, the button is enclosed in a CardSection component.
<Card>
...
<CardSection>
{this.renderButton()}
</CardSection>
</Card>
The CardSection component defines the flexDirection of its children as
'row' (horizontal) and the flex property of the Button "flex: 1" expands the width of the button along the horizontal (row) axis of its parent.
So, to make that code work in current versions of react-native, you have two options:
1.- Enclose the logout button in a CardSection:
import { Header, Button, CardSection } from './components/common';
renderContent() {
if (this.state.loggedIn) {
return (
<CardSection>
<Button>Log Out</Button>
</CardSection>
);
}
return <LoginForm />;
}
2.- Enclose the button in a View and give it at least a style property of "flexDirection: row":
renderContent() {
if (this.state.loggedIn) {
return (
<View style={style.containerStyle}>
<Button>Log Out</Button>
</View>
);
}
return <LoginForm />;
}
const style = {
containerStyle: {
flexDirection: 'row',
}
};
Usually you should wrap your TouchableOpacity sections in Views, they respond much better to styling. When learning react-native i often ran into a similar error.
I like to structure my implementation of buttons like so:
//Note i have edited this to tie in with your code
//
//Button.js file
//
//
return (
<View style = {buttonStyle}>
<TouchableOpacity onPress={onPress}>
<Text style={textStyle}>
{children}
</Text>
</TouchableOpacity>
</View>);
EDIT: Now, you should be able to add a height component to the buttonStyle, and then the button should display as you expect :-) Pseudo code:
//Other styling components...
height: 50,
//Other styling components...
Just add this:
marginTop:5
to the buttonStyle object.
I am using Material UI to make a application Layout. To make my layout responsive i use import ResponsiveMixin from 'react-responsive-mixin';
the ResponsiveMixin's doc doesn't provide me React.Component classes as example, so i try to use this import reactMixin from 'react-mixin'; instead.
here my code:
import
import React from 'react';
import reactMixin from 'react-mixin';
import ResponsiveMixin from 'react-responsive-mixin';
import Paper from 'material-ui/lib/paper';
contentStyle
const contentStyle = {
small: {
height: '100%',
width: '98%',
paddingTop: 60,
marginLeft: '1%',
paddingLeft: 0,
paddingRight: 0
},
medium: {
height: '100%',
width: '90%',
paddingTop: 60,
marginLeft: '5%',
paddingLeft: 0,
paddingRight: 0
},
large: {
height: '100%',
width: '80%',
paddingTop: 60,
marginLeft: 280,
paddingLeft: 40,
paddingRight: 40
}
};
this is my component
export class MainLayout extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.media({maxWidth: 600}, function () {
/*small*/
}.bind(this));
this.media({minWidth: 601, maxWidth: 1024}, function () {
/*medium*/
}.bind(this));
this.media({minWidth: 1025}, function () {
/*large*/
}.bind(this));
}
render() {
const {header, content, footer} = this.props; // destructure this.props to consts
return (
<div>
<header>
{header}
</header>
<main>
<Paper style={contentStyle} zDepth={1}>
{content}
</Paper>
</main>
<footer>
<Paper style={contentStyle}>
{footer}
</Paper>
</footer>
</div>
)
}
}
reactMixin(MainLayout.prototype, ResponsiveMixin);
ResponsiveMixin is located above
componentDidMount(){/contain responsiveMixin Function/}
Thanks for your help :D
Material UI favors inline styles (with its nice theming) so if you want to do it that way, you do it like this:
import React from 'react'
import {Mixins} from 'material-ui'
const {StylePropable, StyleResizable} = Mixins
export default React.createClass({
// Boilerplate and React lifecycle methods
propTypes: {
onChangeMuiTheme: React.PropTypes.func,
},
contextTypes: {
muiTheme: React.PropTypes.object,
},
mixins: [StylePropable, StyleResizable],
getInitialState() {
return {
}
},
// Helpers
getStyles() {
let styles = {
text: {
fontSize: 12,
color: this.context.muiTheme.rawTheme.palette.primary1Color
}
}
// example of a screen-size sensitive style
if (this.isDeviceSize(StyleResizable.statics.Sizes.MEDIUM)) { // active for >= MEDIUM
styles.text.fontSize = 20
}
return styles
},
render() {
let styles = this.getStyles()
return (
<p style={styles.text}>Hello world!</p>
)
}
})