I am not able to navigate to the other screen in my react native project the error is: navigation not found - react-native

const Item = ({ item }) => (
<TouchableOpacity
onPress={() => this.navigation.navigate(
"carProfile",
{item: item}
)}>
<View style={styles.item}>
<Text style={styles.title}>{item.name}</Text>
<Text style={styles.details}>{item.details}</Text>
</View>
</TouchableOpacity>
);
const List = (props,navigation) => {
const renderItem = ({ item }) => {
if (props.searchPhrase === "") {
return <Item item={item} />;
}
if (item.name.toUpperCase().includes(props.searchPhrase.toUpperCase().trim().replace(/\s/g, ""))) {
return <Item item={item} />;
}
if (item.details.toUpperCase().includes(props.searchPhrase.toUpperCase().trim().replace(/\s/g, ""))) {
return <Item item={item} />;
}
};
return (
<SafeAreaView style={styles.list__container}>
<View
onStartShouldSetResponder={() => {
props.setClicked(false);
}}
>
<FlatList
data={props.data}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
</SafeAreaView>
);
};
export default List;
the error is continuing to be there despite me trying to put navigation container in different positions. I want to send the user to the carProfile page, where the data passed in item is reused. This way user can know about the selection they are looking for

Use this way
onPress={() => this.props.navigation.navigate(
"carProfile",
{item: item}
)}

The navigation is inside the props, not as a second argument. Below is a classic example. And also note, you cannot extract navigation prop for child components, it will only work on Main components(Screens).
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
If you want to use navigation inside child components, you can use the navigation hooks.
import { useNavigation } from "#react-navigation/native";
function MyBackButton() {
const navigation = useNavigation();
return (
<Button
title="Back"
onPress={() => {
navigation.goBack();
}}
/>
);
}

Related

How to toggle with map function

I want to use toggle with map function.
I've tried many things, but I returned to the first code. I know what's the problem(I use the map function, but I use only one toggle variable), but I don't know how to fix it.
This is my code.
const [toggle, setToggle] = useState(true);
const toggleFunction = () => {
setToggle(!toggle);
};
{wholeData.map((image)=>{
return(
<TouchableOpacity
key={image.ROWNUM}
onPress={() => navigation.navigate("DetailStore", {
contents: image,
data: wholeData
})}
>
.
.
.
<TouchableOpacity onPress={() => toggleFunction()}>
{toggle ? (
<View style={{marginRight: 11}}>
<AntDesign name="hearto" size={24} color="#C7382A" />
</View>
) : (
<View style={{marginRight:11}}>
<AntDesign name="heart" size={24} color="#C7382A" />
</View>
)}
</TouchableOpacity>
As you've noticed, using a single state for all the toggles won't give you what you want. All you have to do is move your toggle function inside the component you return when you're mapping over your images.
As an unrelated note, you could also simplify your second TouchableOpacity a bit, since the only thing that changes is the icon name.
For example:
// New component
const ListImage = ({ image }) => {
const [toggle, setToggle] = useState(true);
const toggleFunction = () => {
setToggle(!toggle);
};
return (
<TouchableOpacity
key={image.ROWNUM}
onPress={() => navigation.navigate("DetailStore", {
contents: image,
data: wholeData
})}
>
...
<TouchableOpacity onPress={() => toggleFunction()}>
<View style={{ marginRight: 11 }}>
<AntDesign
name={toggle ? "hearto" : "heart"}
size={24}
color="#C7382A"
/>
</View>
</TouchableOpacity>
)
}
// in current component
{wholeData.map((image) => {
return <ListImage image={image} />
})}

FlatList rerender all items favourite

I wanna achieve this effect: when i will press icon item will be added to favourite list and when i press again item will be deleted from favourite list but without rerender all of items from flatlist ( only rerender 1 item ). Now when i press icon all items from the list are rerender. Whats wrong? Items and list of favourite items come from api. They are two arrays of objects. I put id favourite items to array. When id of object is in array you can delete or add to favourite.
snippet of code:
const [fav, setFav] = useState([]); // array of favourites id
const SingleItem = React.memo(({ item, navigation }) => {
return(
<TouchableWithoutFeedback onPress={() => navigation.navigate("xxx", {
id: item.id,
})}>
<View style={styles.singleItemContainer}>
<View style={styles.imageContainer}>
<SliderBox images={images}
ImageComponent={ImageBackground}
ImageComponentStyle={{ width: '90%', marginTop: 10,}}
imageStyle={{borderRadius: 12}}
>
{ route.params?.isLogged &&
<View style={styles.heartIcon}>
<IconFontAwesome name={fav.includes(item.id) ? "paw" : "paw-outline"}
size={30}
color={fav.includes(item.id) ? "red" : "white"}
onPress={() => {
if(fav.includes(item.id)){ // is favourite and delete from favourite
deleteFavourite(item.id)
setFav(fav.filter(el => el != item.id))
}
else{ // add to favourite
addFavourite(item.id)
setFav([item.id, ...fav])
}
}}/>
</View>
}
</SliderBox>
</View>
</View>
</TouchableWithoutFeedback>
)});
const renderItem = ({ item }) => {
return(
<SingleItem
item={item}
navigation={navigation}
/>
);}
return (
<View style={styles.screen}>
<FlatList
data={data}
initialNumToRender={12}
renderItem={renderItem}
keyExtractor={(item) => item.id}
onEndReachedThreshold = {0.2}
onEndReached = {fetchData}
/>
</View>
);
};

Why does FlatList scrolls to top when I select an item

I have a FlatList with TouchableOpacity items. When I try to select an item, the list scrolls to top.
This is the Collapsible content;
const setBrandSelected = index => {
var temp = JSON.parse(JSON.stringify(tempFilterOptions));
temp[0].enums[index].selected = !temp[0].enums[index].selected;
setTempFilterOptions(temp);
};
const FilterOptionBrand = () => {
const RenderBrand = ({ item, index }) => {
return (
<TouchableOpacity onPress={setBrandSelected.bind(null, index)}>
{item.selected && (
<View style={[styles.brandImage, styles.selectedBrandImage]}>
<Icon iconName={iconNames.Tick} />
</View>
)}
<FastImage source={{ uri: item.logo }} style={styles.brandImage} resizeMode={FastImage.resizeMode.contain} />
<Text style={styles.brandName}>{item.name}</Text>
</TouchableOpacity>
);
};
const BrandSeparator = () => <View style={styles.brandSeparator} />;
return (
<View style={styles.filterBrandMainContainer}>
<View style={styles.searchBrandContainer}>
<View style={styles.magnifyingGlassWrapper}>
<Icon iconName={iconNames.MagnifyingGlass} />
</View>
<TextInput style={styles.searchBrandInput} placeholder={searchBrandText} />
</View>
<FlatList
horizontal={true}
showsHorizontalScrollIndicator={false}
keyExtractor={(item, index) => String(item.id)}
style={styles.collapsibleContainer}
data={tempFilterOptions[0].enums}
renderItem={RenderBrand}
ItemSeparatorComponent={BrandSeparator}
></FlatList>
</View>
);
};
If you somehow stumble upon this question. The answer is wherever the problem occurs be it Header be it Footer. You should call the component function and not directly just type the function.
const Header = () => <View />
Correct usage;
ListHeaderComponent={Header()}
Incorrect usage;
ListHeaderComponent={Header}

React-Native modal not showing FlatList Items

Modal only displays button but not FlatList item.
I am trying to build a custom app picker for my react-native-app which renders a list of items on a modal.
AppPicker.js
const AppPicker = ({ icon, items, placeholder }) => {
const [modalVisible, setModalVisible] = React.useState(false)
return (
<>
<TouchableWithoutFeedback onPress={() => setModalVisible(true)} >
<View style={styles.container}>
{icon && <MaterialCommunityIcons name={icon} size={20} style={styles.icon} />}
<AppText style={styles.text}> {placeholder} </AppText>
<MaterialCommunityIcons name="chevron-down" size={20} />
</View>
</TouchableWithoutFeedback>
<Modal visible={modalVisible} animationType="slide" >
<Button title="Close" onPress={() => setModalVisible(false)} />
<FlatList
data={items}
keyExtractor={item => item.value.toString()}
renderItem={({ item }) =>
<PickerItem
lable={item.label}
onPress={() => console.log(item)}
/>}
/>
</Modal>
</>
)
}
the <PickerItem/> that should be rendered by the flatlist is a component that just displays the items from the list.
PickerItem.js
const PickerItem = ({ label, onPress }) => {
return (
<TouchableOpacity onPress={onPress}>
<AppText> {label} </AppText>
</TouchableOpacity>
)
}
export default PickerItem;
when I randomly tap on the modal screen however the onPress() on the FlatList triggers the console.log(item) and the items are displayed on the console. Any help on this will be appreciated.
** App.js **
const categories = [
{ label: "furniture", value: 1 },
{ label: "clothing", value: 2 },
{ label: "phone", value: 3 },
]
export default function App() {
return (
<Screen style={styles.container}>
<AppPicker items={categories} icon="apps" placeholder="category" />
<AppTextInput icon="email" placeholder="email" />
</Screen>
);
}
NOTE: I am using expo to run the application.

React Native undefined is not an object (evaluating 'props.navigation.toggleDrawer')

I'm new to react native and so I'm wondering why I'm receiving an error like
"undefined is not an object (evaluating 'props.navigation.toggleDrawer')" when I try to click on hamburger menu in my Home
Here below my Home.js
const NavigatorHome = props => {
return (
<View>
<AppHeader navigation={props.navigation} title="Home" />
</View>
);
};
export default class Home extends Component {
state = {
users: []
}
async componentDidMount() {
const users = await ajax.fetchUsers();
//ET20200226 This was a warning
this.setState({users});
}
render() {
return (
<View>
<NavigatorHome></NavigatorHome>
<View>
<Text style={styles.h2text}>
List of requests
</Text>
<FlatList
data={this.state.users}
showsVerticalScrollIndicator={false}
renderItem={({item}) =>
<View style={styles.flatview}>
<Text style={styles.uuid}>{item.uuid}</Text>
</View>
}
keyExtractor={item => item.uuid}
/>
</View>
</View>
);
}
}
Here my AppHeader.js
const AppHeader = props => {
return (
<Header
//leftComponent={<HamburgerMenu navigation={props.navigation} />}
leftComponent={<Icon
color="#fff"
name="menu"
onPress={() => props.navigation.toggleDrawer()}
/>}
centerComponent={{
text: props.title,
style: { color: "#fff", fontWeight: "bold" }
}}
statusBarProps={{ barStyle: "light-content" }}
/>
);
};
export default AppHeader;
Can someone help me to figure out how to fix it?
The reason for the error is that props.navigation is undefined in NavigatorHome. you must pass props.navigation to NavigatorHome. Your code should be as follows:
<View>
<NavigatorHome navigation={this.props.navigation}></NavigatorHome>
<View>