I have a Button element here at the bottom. onPress somehow is not rendering my function - 'barCharts' - I wonder why it's not showing up the component upon click. I am using buttons from the react-native paper library.
import * as React from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { Button, Menu, Divider, Provider, TextInput } from 'react-native-paper';
import { BarChart, LineChart, Grid } from 'react-native-svg-charts';
import { Colors } from 'react-native/Libraries/NewAppScreen';
const App = () => {
const barCharts = () => {
const fill = 'rgb(134, 65, 244)'
const data = [50, 10, 40, 95, -4, -24, null, 85, undefined, 0, 35, 53, -53, 24, 50, -20, -80]
return (
<View style={styles.sectionContainer}>
<BarChart style={{ height: 200 }} data={data} svg={{ fill }} contentInset={{ top: 30, bottom: 30 }}>
<Grid />
</BarChart>
</View>
);
};
const [visible, setVisible] = React.useState(false);
const openMenu = () => setVisible(true);
const closeMenu = () => setVisible(false);
return (
<Provider>
<View
style={{
paddingTop: 50,
flexDirection: 'row',
justifyContent: 'center',
}}>
<Menu
visible={visible}
onDismiss={closeMenu}
anchor={<Button onPress={openMenu}>Show menu</Button>}>
<Menu.Item onPress={() => {}} title="Item 1" />
<Menu.Item onPress={() => {}} title="Item 2" />
<Divider />
<Menu.Item onPress={() => {}} title="Item 3" />
</Menu>
</View>
<View style={styles.sectionContainer}>
<Button onPress={barCharts}>Show barCharts</Button>
</View>
</Provider>
);
};
export default App;
you are rendering the entire component inside the button - this will not be able to show. What you actually intended to do is more like
const fill = 'rgb(134, 65, 244)'
const data = [50, 10, 40, 95, -4, -24, null, 85, undefined, 0, 35, 53, -53, 24, 50, -20, -80]
const barCharts = (
<View style={styles.sectionContainer}>
<BarChart style={{ height: 200 }} data={data} svg={{ fill }} contentInset={{ top: 30, bottom: 30 }}>
<Grid />
</BarChart>
</View>
);
<View style={styles.sectionContainer}>
<Button onPress={() => setShowBarCharts(true)}>Show barCharts</Button>
</View>
{showBarCharts && barcharts}
This would ensure that the barcharts show on the click of the button.
edit: adding a bit for how to change the barcharts component - it is a function currently. i suspect you will have to render a jsx element.
Related
I am creating a header with a drawer navigator and Expo. I have made a drawer navigator but the position is not changing even after using: drawerPosition="right".
Also, I want to create a custom header and need to integrate this drawer navigator in that header. My code is something like this:
import * as React from 'react';
import { View, Text, Image, TouchableOpacity, Button } from 'react-native';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
} from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import News from "./Components/News";
const Drawer = createDrawerNavigator();
const CustomDrawer = props => {
return (
<View style={{ flex: 1 }}>
<DrawerContentScrollView {...props}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 20,
backgroundColor: '#f6f6f6',
marginBottom: 20,
}}
>
<View>
<Text>John Doe</Text>
<Text>example#email.com</Text>
</View>
<Image
source={{
uri: 'https://cdn.pixabay.com/photo/2015/01/08/18/29/entrepreneur-593358_1280.jpg',
}}
style={{ width: 65, height: 65, borderRadius: 30 }}
/>
</View>
<DrawerItemList {...props} />
</DrawerContentScrollView>
<TouchableOpacity
style={{
position: 'absolute',
right: 0,
left: 0,
bottom: 50,
backgroundColor: '#f6f6f6',
padding: 20,
}}
>
<Text>Log Out</Text>
</TouchableOpacity>
</View>
);
};
const DrawerNavigator = () => {
return (
<Drawer.Navigator
drawerPosition="right"
screenOptions={{
headerShown: true,
headerStyle: {
backgroundColor: 'transparent',
elevation: 0,
shadowOpacity: 0,
},
headerTitle: '',
}}
drawerContent={props => <CustomDrawer {...props} />}
>
<Drawer.Screen component={News} name='Home' />
</Drawer.Navigator>
);
};
export default function App() {
return (
<NavigationContainer>
<DrawerNavigator />
</NavigationContainer>
);
}
I have seen many tutorials and read documentation yet no results. Can please someone help me
![Text] (Actual)
![Text] (Expected)
is anyone able to help pass the data to the modal? The .map function returns the month names from the data [] array (needed for the slider), and I'd like to display that particular one in a modal view as well.
Current view:
and modal:
expectations:
unfortunately, only the first month from the [] is visible in the modal.
I am also putting the .js file for review:
import React, { useContext, useState } from 'react';
import { AuthenticatedUserContext } from '../AuthenticatedUserProvider';
import { Swiper } from 'react-native-swiper';
import Modal from 'react-native-modal';
import { db } from '../firebase';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import { View, Text, TouchableHighlight, StyleSheet, Button, TextInput, TouchableOpacity } from 'react-native';
const data = [
{ id: 1, name: 'Month1' },
{ id: 2, name: 'Month2' },
{ id: 3, name: 'Month3' }
];
export default function HomeScreen() {
const { user } = useContext(AuthenticatedUserContext);
const [ isModalVisible, setModalVisible ] = useState(false);
const [ months, setMonths ] = useState(data);
const [ values, setValues ] = useState({
budget: '',
month: '',
});
const toggleModal = () => {
setModalVisible(!isModalVisible);
};
const onSave = () => {
setValues({ ...values, userId: user.uid });
setModalVisible(!isModalVisible);
db.collection('Budget').add({
userId: user.uid,
budget: values.budget,
});
};
return (
<Swiper showsButtons={true} showsPagination={false} buttonWrapperStyle={{ alignItems: 'flex-start' }}>
{months.map((months, i) => (
<View key={i} style={styles.slider}>
<Text style={styles.text}> {months.name}</Text>
<View>
<View style={styles.mainCardView}>
<TouchableOpacity
onPress={
toggleModal
}
style={{ flex: 1, alignItems: 'flex-end', marginTop: 20 }}
>
<FontAwesome name="pencil-square-o" color="black" size={30} />
</TouchableOpacity>
</View>
</View>
<Modal isVisible={isModalVisible} style={{ margin: 0 }}>
<Text style= {{marginLeft: 50, color: '#fff'}}>Current month: {months.name}</Text>
<TextInput
style={{
height: 40,
borderColor: 'white',
borderWidth: 1,
color: 'white',
shadowColor: 'white',
margin: 50,
padding: 5,
marginVertical: 10,
}}
onChange={(e) => setValues({ ...values, budget: e.target.value })}
value={values.budget}
placeholder="Budget"
keyboardType="decimal-pad"
placeholderTextColor="#fff"
/>
<TouchableHighlight
style={{
height: 40,
borderRadius: 10,
backgroundColor: 'gray',
marginLeft: 50,
marginRight: 50,
marginTop: 20,
}}
>
<Button
onPress={onSave}
title="Confirm"
/>
</TouchableHighlight>
<TouchableHighlight
style={{
height: 40,
borderRadius: 10,
backgroundColor: 'gray',
marginLeft: 50,
marginRight: 50,
marginTop: 20,
}}
>
<Button
onPress={toggleModal}
title="Back"
/>
</TouchableHighlight>
</Modal>
</View>
))}
</Swiper>
);
}
Here are a couple suggestions:
{months.map((months, i) => (...))} I would not recommend using months as the current item in the map since its confusing. Instead, I would recommend something like months.map((month, i) => ())} since in actuality you are referring to just one month within the map.
You are rendering the modal within your map, so each month has its own modal. But you only render one modal at a time, so instead you can just put the modal outside of the map, and somehow point the modal to the currently active month (see below)
If you have another piece of state like const [activeMonth, setActiveMonth] = useState(). Then when you click one of the months you can set the modal state to open, and set the activeMonth state. Then in the modal, it would just display state based off the current active month. It seems like you can make use of your values state to do that probably!
I am new to react native.
I created some custom components in project. And I pass some style to them via the props but my passing styles are not attached to that components. At the first it was working correctly but suddenly I don't know what happened that my passing styles are not working.
Here is my code:
This the page where I used my custom component and passed style to that.
function StartGameScreen(props) {
const [confirmed, setConfirmed] = useState(false);
const [selectedNumber, setSelectedNumber] = useState();
const numInputHandler = (inputText) => {
setEneteredValue(inputText.replace(/[^0-9]/g, ""));
};
const confirmInput = () => {
const chosenNumber = parseInt(enteredValue);
if (isNaN(chosenNumber) || chosenNumber <= 0 || chosenNumber > 99) {
Alert.alert(
"Invalid number!",
"Number has to be a number between 0 and 99.",
[{ text: "Okay", style: "destructive", onPress: resetInput }]
);
return;
}
setConfirmed(true);
setSelectedNumber(chosenNumber);
setEneteredValue("");
Keyboard.dismiss();
};
let confirmedOutput;
if (confirmed) {
confirmedOutput = (
<Card style={styles.summeryContainer}>
<Text>You selected</Text>
<NumberContainer>{selectedNumber}</NumberContainer>
<Button
title="START GAME"
onPress={() => {
console.log("hello" + selectedNumber);
props.onStartGame(selectedNumber);
}}
/>
</Card>
);
}
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}
>
<View style={styles.container}>
<Text style={styles.title}>Start A New Game!</Text>
*This is where I used my custom component (<Card>).*
<Card style={styles.inputContainer}>
<Text>select a number</Text>
<Input
style={styles.input}
blurOnSubmit
autoCapatilize="none"
autoCorrect={false}
keyboardType="number-pad"
maxLength={2}
onChangeText={numInputHandler}
value={enteredValue}
/>
<View style={styles.buttonCon}>
<View style={styles.button}>
<Button
title="Reset"
color={Colors.accent}
onPress={resetInput}
/>
</View>
<View style={styles.button}>
<Button
title="Confirm"
color={Colors.primary}
onPress={confirmInput}
/>
</View>
</View>
</Card>
{confirmedOutput}
</View>
</TouchableWithoutFeedback>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 10,
alignItems: "center",
},
inputContainer: {
width: 300,
maxWidth: "80%",
alignItems: "center",
},
input: {
textAlign: "center",
width: 50,
},
});
export default StartGameScreen;
And this is my Card custom component:
function Card(props) {
return (
<View style={{ ...styles.container, ...props.style }}>
{props.children}
</View>
);
}
const styles = StyleSheet.create({
container: {
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.26,
shadowRadius: 6,
elevation: 12,
backgroundColor: "white",
padding: 20,
borderRadius: 10,
},
});
export default Card;
Change Your Card component like below then it will work
function Card(props) {
return (
<View style={[styles.container,props.style]}>
{props.children}
</View>
);
}
I'm learning react native, and I ran into this problem, I'm trying to export a Class to another Screen, but "View config getter callback for component... must be a function" appears, if anyone can help me I'll be extremely grateful, I'll print de code below. Should I change the Class for a function? Is there any other way to export this code as a Class?
import React from 'react';
import { StyleSheet, Dimensions, ScrollView } from 'react-native';
import { Button, Block, Text, Input, theme } from 'galio-framework';
const { width } = Dimensions.get('screen');
export default class menuLateral extends React.Component {
renderSearch = () => {
const { navigation } = this.props;
const iconCamera = <Icon size={16} color={theme.COLORS.MUTED} name="zoom-in" family="material" />
return (
<Input
right
color="black"
style={styles.search}
iconContent={iconCamera}
placeholder="What are you looking for?"
onFocus={() => navigation.navigate('Pro')}
/>
)
}
renderTabs = () => {
const { navigation } = this.props;
return (
<Block row style={styles.tabs}>
<Button shadowless style={[styles.tab, styles.divider]} onPress={() => navigation.navigate('Pro')}>
<Block row middle>
<Icon name="grid" family="feather" style={{ paddingRight: 8 }} />
<Text size={16} style={styles.tabTitle}>Categories</Text>
</Block>
</Button>
<Button shadowless style={styles.tab} onPress={() => navigation.navigate('Pro')}>
<Block row middle>
<Icon size={16} name="camera-18" family="GalioExtra" style={{ paddingRight: 8 }} />
<Text size={16} style={styles.tabTitle}>Best Deals</Text>
</Block>
</Button>
</Block>
)
}
}
const styles = StyleSheet.create({
home: {
width: width,
},
search: {
height: 48,
width: width - 32,
marginHorizontal: 16,
borderWidth: 1,
borderRadius: 3,
},
tabs: {
marginBottom: 24,
marginTop: 10,
elevation: 4,
},
tab: {
backgroundColor: theme.COLORS.TRANSPARENT,
width: width * 0.50,
borderRadius: 0,
borderWidth: 0,
height: 24,
elevation: 0,
},
tabTitle: {
lineHeight: 19,
fontWeight: '300'
},
divider: {
borderRightWidth: 0.3,
borderRightColor: theme.COLORS.MUTED,
},
})
React components have to start with a capital letter so that's the first issue. Second issue is that react components need a render function.
I have tried formatting the X-axis to display dates in order, but some of the points are still not showing. Here's a link for viewing the chart and editing - https://snack.expo.io/#anushkas/4cfb05
The very first label is suppose to be '09-10-2020' , it shows as '10-2020'. I am using react-native-svg-charts library.
import React from 'react';
import {LineChart, XAxis, YAxis} from 'react-native-svg-charts';
import {View, Text} from 'react-native';
import {Svg, Line, Circle, G, Rect} from 'react-native-svg';
export default class CustomLineChartOne extends React.PureComponent {
handleFill = (value) => {
if (value > 100) {
return 'rgba(190, 30, 45, 0.5)';
} else if (value > 80 && value <= 100) {
return 'yellow';
} else {
return '#CCE6D0';
}
};
render() {
const xAxisLabels = [
'09-10-2020',
'10-10-2020',
'11-10-2020',
'12-10-2020',
];
const data = [50, 10, 40, 95];
const Decorator = ({x, y, data}) => {
return data.map((value, index) => (
<View>
<Rect
x={x(index) - 1.75}
y={y(value + 8)}
width="4"
height="40"
rx="2"
fill={this.handleFill(value)}
/>
<Circle
key={index}
cx={x(index)}
cy={y(value)}
r={2}
stroke={'#639123'}
fill={'#606060'}
/>
</View>
));
};
return (
<View
style={{
height: 200,
flexDirection: 'row',
}}>
<YAxis
data={data}
contentInset={{top: 20, bottom: 20}}
svg={{
fill: 'black',
fontSize: 10,
}}
/>
<View style={{flex: 1}}>
<LineChart
style={{flex: 1}}
data={data}
svg={{stroke: 'rgb(134, 65, 244)'}}
contentInset={{top: 10, bottom: 10, left: 10, right: 10}}>
<Decorator />
</LineChart>
<XAxis
data={data}
formatLabel={(value, index) => xAxisLabels[index]}
contentInset={{ left: 10, right: 10 }}
svg={{ fontSize: 8, fill: '#3A8F98' }}
/>
</View>
</View>
);
}
}
To XAxis component, give contentInset value of 15 to left and right, 10 seems bit low, if it's still hiding then increase it a bit more:
<XAxis
data={data}
formatLabel={(value, index) => xAxisLabels[index]}
contentInset={{ left:15, right: 15 }}
svg={{ fontSize: 8, fill: '#3A8F98' }}
/>