How to fix Require cycle warning In React Expo - react-native

I'm getting this error.[ErrorImg][1]
This is Require cycles error but I can't find what is the reason.
I want to use ListItem component to View.js through component.js and I already use that like this import {ListItem } from '../components/';.
The result is good but there is this warning and I want to fix. Please help me.
Require cycle: Components.js->
import Button from './Button';
import Select from './Select';
import Icon from './Icon';
import Tabs from './Tabs';
import Product from './Product';
import Drawer from './Drawer';
import Header from './Header';
import Switch from './Switch';
import ListItem from './ListItem';
import HorizontalListItem from './HorizontalListItem';
export {
Button,
Select,
Icon,
Tabs,
Product,
Drawer,
Header,
Switch,
ListItem,
HorizontalListItem,
};```
View.js->
```const renderPatientsList = () => {
return(
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<ScrollView vertical={true} showsVerticalScrollIndicator={false} style={{marginBottom: theme.SIZES.BASE * 3}}>
<ListItem product={products[0]} horizontal />
<ListItem product={products[1]} horizontal />
<ListItem product={products[2]} horizontal />
</ScrollView>
</Block>
)
}```
ListItem.js -->
```import React from 'react';
import { withNavigation } from '#react-navigation/compat';
import { StyleSheet, Dimensions, Image, TouchableWithoutFeedback } from 'react-native';
import { Block, Text, theme } from 'galio-framework';
import { Icon } from '../components/';
import { LinearGradient } from 'expo-linear-gradient';
const { width } = Dimensions.get('screen');
const ListItem = props => {
const { navigation, product, horizontal, full, style, priceColor, imageStyle, time, unReaden, weekday } = props;
const imageStyles = [styles.image, full ? styles.fullImage : styles.horizontalImage, imageStyle];
return (
<Block row={horizontal} card flex style={[styles.product, styles.shadow, style]}>
<TouchableWithoutFeedback onPress={() => navigation.navigate('Product', { product: product })}>
<Block style={[styles.imageContainer, styles.shadow]}>
<Image source={{ uri: product.image }} style={imageStyles}/>
</Block>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={() => navigation.navigate('Product', { product: product })}>
<Block flex={3}>
<Text size={16} style={styles.userName}>{product.title}</Text>
<Block flexDirection={'row'}>
<Icon name="photo" family="font-awesome" color={theme.COLORS.MUTED} size={theme.SIZES.BASE} style={styles.icons}> </Icon>
<Icon name="check" family="font-awesome" color={theme.COLORS.MUTED} size={theme.SIZES.BASE} style={styles.icons}> </Icon>
<Text size={16} muted={!priceColor} color={priceColor}>${product.price}</Text>
</Block>
</Block>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={() => navigation.navigate('Product', { product: product })}>
<Block flex={1}>
<>
{(product.time) ? (
<Text size={12} style={styles.times} color={"#06D81E"}>{product.time}</Text>
) : (
<Text size={12} style={styles.times} color={"#000"}>{product.weekday}</Text>
)}
</>
<Block style={{borderRadius: 100, backgroundColor: "#06D81E", width: theme.SIZES.BASE * 1.2, height: theme.SIZES.BASE * 1.2, position: "absolute", right: theme.SIZES.BASE, bottom: theme.SIZES.BASE}}>
<Text size={12} center style={{justifyContent: 'center', alignItems: 'center'}} color={"#FFF"} fontWeight={"semiBold"}>{product.unReaden}</Text>
</Block>
</Block>
</TouchableWithoutFeedback>
</Block>
);
}```
[1]: https://i.stack.imgur.com/rDB6i.png

You are getting require cycle warning because you end up creating a loop ( require from Component.js in ListItem.js and require from ListItem.js in Component.js)
In ListItem.js,
import {Icon} from Icon.js
The general idea is to write the module in another file and import that module from there.
see this for a detailed explanation:
Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle

Related

ReactNative send style as props to component

I am new to learning React Native and I would like to build a (ReactNaive & Expo) application with a good interface look, How can I build a component and send style{backgroundColor} as props then render the component on Home
home.js
import React from 'react'
import { View, Text , Image , ScrollView} from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import { COLORS, SIZES,FONTS} from '../styles/theme.js';
import Category from '../components/Category.js';
import CategorySlider from '../components/CategorySlider'
const Home = () => {
function renderHeader(){
return(
<View
style = {{
flexDirection: 'row' ,
marginTop: 40,
marginBottom: 10,
paddingHorizontal:SIZES.padding,
alignItems : 'center'
}}
>
<View style={{flex:1}}>
<Text >Hello , Wafa</Text>
</View>
{/* Nonfiction Button */}
</View>
)}
return (
<View
style ={{
flex: 1,
backgroundColor: COLORS.white
}}
>
{/* HEADER */}
{renderHeader()}
{/* Content */}
<View style={{height:130 , marginTop:SIZES.margin}}>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
>
<Category name='Balance' />
<Category name='Saving' style={COLORS.green} />
<Category name='Income' style={ COLORS.brown } />
<Category name='Loans' style={ COLORS.pink}/>
<Category name='Saving' style={ COLORS.pink}/>
<Category name='Saving' style={ COLORS.pink}/>
</ScrollView>
</View>
<CategorySlider/>
</View>
)
}
export default Home;
It is the component I want to render on home.js
Category.js
import React, { PureComponent } from 'react'
import { Text, View ,StyleSheet ,Image } from 'react-native'
import { backgroundColor } from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
import { COLORS, SIZES,FONTS} from '../styles/theme.js';
export default class Category extends PureComponent {
render() {
return (
<View style={{marginLeft: SIZES.margin ,marginRight: SIZES.margin}}>
<View>
<View style={{
height: 60,
width: 60,
backgroundColor:COLORS.pink,
borderRadius: SIZES.radius,
}}>
<View />
<View>
<Image />
</View>
</View>
<Text
style={{textAlign:'center'}}
>
{this.props.name}</Text>
</View>
</View>
)
}
}
l made also File for Design system contains style I will repeat on the application.
theme.js:
import { Dimensions } from "react-native";
import { useFonts } from 'expo-font';
const { width, height } = Dimensions.get("window");
export const COLORS = {
green: "#68AB9F",
brown: "#c18e62",
pink: "#d99e96" ,
gray: "#383e42",
white: "#f5f7fc",
}
Here you're working on one with a Functional based component (home.js) and one with Class-based (Category.js). Standard is if first convert your Category component with functional then you can save that props to your Category component like:
import React, { useState } from 'react'
import { Text, View ,StyleSheet ,Image } from 'react-native'
import { backgroundColor } from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
import { COLORS, SIZES,FONTS} from '../styles/theme.js';
const Category = (props) => {
const [backgroundColor, setBackgroundColor] = useState(props.style || null); //store your prop in state like this
const [name, setName] = useState(props.name || null);
return (
<View style={{marginLeft: SIZES.margin ,marginRight: SIZES.margin}}>
<View>
<View style={{
height: 60,
width: 60,
backgroundColor: backgroundColor,
borderRadius: SIZES.radius,
}}>
<View />
<View>
<Image />
</View>
</View>
<Text
style={{textAlign:'center'}}
>
{name}</Text>
</View>
</View>
)
}
export default Category;
Hope this works for you.
In your parent component take your style object in the wrapper of child component i.e.
function Parent(){
return (
<Child cssdata={{backgroundColor:'red',marginLeft:8}}/>
)
}
and in your child component take this data from props and applied to it
function Child(props){
return (
<View style={props.cssdata}></View>
)
}

React Native - FlatList not rendering images and Text

I'm doing a welcome flatlist for the first-time users, I have an image and text to be shown, but it does not render any image, what am I doing wrong? When I put the path in the View it works, but when I put in the imagePath it shows a blank screen
import React from 'react';
import {
View,
Text,
Image,
TouchableOpacity,
FlatList,
} from 'react-native';
import ProgressCircle from 'react-native-progress-circle';
import Icon from 'react-native-vector-icons/AntDesign';
import {SafeAreaView} from 'react-native-safe-area-context';
import {TextInput, Button} from 'react-native-paper';
import styles from './styles';
import {blue} from 'chalk';
<FlatList
horizontal={true}
data={onboardingList}
renderItem={this.Welcome}
keyExtractor={(item, index) => index.toString()}
/>;
const onboardingList = [
{
screenText1: 'Get weekly overviews and find',
screenText2: 'out whats impacting your health',
screenText3: 'and wellness.',
imagePath: require('../../assets/images/wellbeing.png'),
nextScreen: 'HabitTracking',
progressCirclePercentage: 20,
},
{
screenText1: 'Explore healthyroutines and get',
screenText2: 'reminders to stay motivated along',
screenText3: 'the way.',
imagePath: require('../../assets/images/HabitTracking.png'),
nextScreen: 'Recommendation',
progressCirclePercentage: 40,
},
];
const Welcome = (item, navigation) => {
return (
<View style={styles.container}>
<View>
<Image source={item.imagePath} style={styles.image} />
</View>
<View style={styles.text_field}>
<Text style={styles.textContent}>{item.screenText1}</Text>
<Text style={styles.textContent}>{item.screenText2}</Text>
<Text style={styles.textContent}>{item.screenText3}</Text>
</View>
<View style={styles.footer}>
<TouchableOpacity onPress={() => navigation.navigate(item.nextScreen)}>
<ProgressCircle
percent={item.progressCirclePercentage}
radius={30}
borderWidth={2}
color="#3399FF"
shadowColor="white"
bgColor={'white'}>
<Icon name="arrowright" size={25} color="black"></Icon>
</ProgressCircle>
</TouchableOpacity>
</View>
</View>
);
};
export default Welcome;
Bonus question, the progressCircle is not getting the numbers I'm giving on progressCirclePercentage
Found the solution, the problem was on my View, I was using item.screenText and it should be only screentext
<View style={styles.container}>
<View>
<Image source={imagePath} style={styles.image} />
</View>
<View style={styles.text_field}>
<Text style={styles.textContent}>{screenText1}</Text>
<Text style={styles.textContent}>{screenText2}</Text>
<Text style={styles.textContent}>{screenText3}</Text>
</View>
<View style={styles.footer}>
<TouchableOpacity onPress={() => handleModal(2)}>
<ProgressCircle
percent={progressCirclePercentage}
radius={30}
borderWidth={2}
color="#3399FF"
shadowColor="white"
bgColor={'white'}>
<Icon name="arrowright" size={25} color="black"></Icon>
</ProgressCircle>
</TouchableOpacity>
</View>
</View>

react native keyboard dismiss not working

can anyone explain me why keyboard dismiss not works ? No errors and nothing happens.
In my last project it works, but not there. What do I am wrong?
Code:
import React, { useState, useEffect } from 'react';
import { StyleSheet, View, Text, TextInput, TouchableOpacity, KeyboardAvoidingView, ScrollView, Dimensions, Keyboard } from 'react-native';
import { AntDesign } from '#expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
const Home = () => {
const [searchInput, setSearchInput] = useState('');
return (
<KeyboardAvoidingView onPress={() => Keyboard.dismiss()} style={styles.container}>
<LinearGradient
style={styles.header}
colors={['blue', 'red', 'orange']}
>
<View style={{alignItems: 'flex-end'}}>
<TouchableOpacity>
<AntDesign style={{textAlign: 'right'}} name="pluscircleo" size={42} color="#fff" />
</TouchableOpacity>
</View>
<View style={styles.headerBottom}>
<Text style={styles.headerText}>Treffpunkt</Text>
<TextInput
placeholder="Gebe deinen Code ein"
value={searchInput}
onChangeText={value => setSearchInput(value)}
style={styles.searchInput}
/>
</View>
</LinearGradient>
</KeyboardAvoidingView>
)
};
As Konstantin had mentioned in the comment, KeyboardAvoidingView does not have an onPress event.
You can have a child element before the gradient that will handle the press for you.
You can refer to the expo example here
<KeyboardAvoidingView
style={styles.container}>
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<LinearGradient
style={styles.header}
colors={['blue', 'red', 'orange']}>
<View style={{ alignItems: 'flex-end' }}>
...
</View>
</LinearGradient>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>

React Native Elements Checkbox SetState is not a function

Have implemented a screen that uses checkboxes.
Following the example from React Native Checkbox
On clicking a checkbox, receive the following error:
TypeError: _this.setState is not a function. (In '_this.setState({
checked: !_this.state.checked
})', '_this.setState' is undefined)
Below is my code:
import * as React from 'react';
import {Dimensions, StyleSheet, View} from 'react-native';
import {Button, Card, CheckBox} from 'react-native-elements';
function MyScreen({navigation}) {
return (
<View style={styles.view}>
<View style={styles.panel}>
<Card containerStyle={styles.card} title="My Checkboxes">
<CheckBox
title="My Checkbox"
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})}
/>
</Card>
<Button
style={styles.button}
title="Done"
onPress={() => navigation.navigate('Home')}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
view: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
panel: {
width: Dimensions.get('window').width,
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
top: 0,
},
button: {
margin: 5,
width: 150,
height: 50,
},
card: {
width: Dimensions.get('window').width,
marginBottom: 20,
},
});
export default MyScreen;
I've tried searching here, and pretty much everywhere, and can't seem to find a solution.
Any assistance would be appreciated.
You are using a functional component.
Change it to a class component or use hooks inside this functional component.
Change your code as following
class component
import React, { Component } from 'react'
import {Dimensions, StyleSheet, View} from 'react-native';
import {Button, Card, CheckBox} from 'react-native-elements';
export default class App extends Component {
state={ checked: false };
render() {
return (
<View style={styles.view}>
<View style={styles.panel}>
<Card containerStyle={styles.card} title="My Checkboxes">
<CheckBox
title="My Checkbox"
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})}
/>
</Card>
<Button
style={styles.button}
title="Done"
onPress={() => navigation.navigate('Home')}
/>
</View>
</View>
)
}
}
or functional component
import React, {useState} from 'react';
import {Dimensions, StyleSheet, View} from 'react-native';
import {Button, Card, CheckBox} from 'react-native-elements';
function MyScreen({navigation}) {
const [checked, toggleChecked] = useState(false);
return (
<View style={styles.view}>
<View style={styles.panel}>
<Card containerStyle={styles.card} title="My Checkboxes">
<CheckBox
title="My Checkbox"
checked={checked}
onPress={() => toggleChecked(!checked)}
/>
</Card>
<Button
style={styles.button}
title="Done"
onPress={() => navigation.navigate('Home')}
/>
</View>
</View>
);
}
If you are using your functional component as a child in another component, you can have use props instead.
function MyScreen({navigation, onChecked, checked}) {
return (
<View style={styles.view}>
<View style={styles.panel}>
<Card containerStyle={styles.card} title="My Checkboxes">
<CheckBox
title="My Checkbox"
checked={checked}
onPress={onChecked}
/>
</Card>
<Button
style={styles.button}
title="Done"
onPress={() => navigation.navigate('Home')}
/>
</View>
</View>
);
}
MyScreen.propTypes = {
checked: PropTypes.bool.isRequired,
onChecked: PropTypes.func.isRequired
};
export default MyScreen;
On the parent component the onChecked can look like:
onChecked =()=>{
...
this.setState({checked: !this.state.checked})
}
Also in the parent component, you can use MyScreen as:
<MyScreen
onCheck={this.onChecked}
checked={this.state.checked}
/>

Element type is invalid: Expected String

I checked all code but didn't found the mistake which can cause such a strange error. As you see it's exported while it says you likely forget to export. Here is the code with the full list of imports:
import "expo";
import React from "react";
import {Image, TouchableHighlight} from "react-native";
import {
Content,
Left,
Right,
Icon,
CardItem,
Card,
Button,
Text,
Body,
Row,
Col,
Grid,
Thumbnail,
ScrollView
} from "native-base";
import {dataRow1,dataRow2,dataRow3,dataRow4} from "../data/HomeData";
import { primary, secondary, grey } from '../styles/variables';
const HomeContent = props => {
return (
<Content>
<ScrollView horizontal>
{dataRow1.map((item, idx) => {
return <CardItemContainer {...props} key={idx} item={item} />;
})}
</ScrollView>
<ScrollView horizontal>
{dataRow2.map((item, idx) => {
return <CardItemContainer {...props} key={idx} item={item} />;
})}
</ScrollView>
<ScrollView horizontal>
{dataRow3.map((item, idx) => {
return <CardItemContainer {...props} key={idx} item={item} />;
})}
</ScrollView>
<ScrollView horizontal>
{dataRow4.map((item, idx) => {
return <CardItemContainer {...props} key={idx} item={item} />;
})}
</ScrollView>
</Content>
);
};
const CardItemContainer = ({item, navigation}) => {
return (
<Card style={{marginBottom: 10}}>
<TouchableHighlight onPress={() => navigation.navigate("Items")}>
<CardItem cardBody>
<Image
source={item.image}
style={styles.img}
/>
</CardItem>
</TouchableHighlight>
<CardItem>
<Text style={{color:grey}}> {item.title} </Text>
</CardItem>
</Card>
);
};
const styles = {
img:{
height: 200,
width: null,
flex: 1
},
}
export default HomeContent;
What can cause it and what is wrong? Can you help me please to solve this issue?
Thanks in advance!
It looks like you have not imported any html tag reference from react-native. Every HTML tag is a element.
Let's suppose if you have Text tag then you must import it like import { Text} from react-native .
You should import ScrollView from react-native instead of native-base.
After removing ScrollView from native base import's line include it in react-native's import line like this:
import {Image, TouchableHighlight, ScrollView} from "react-native";