I'm using using this data to fill a FlatList, each item contains a LinearGradient
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
firstColor: "#f472a7",
secondColor: "#d84351"
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
firstColor: "#50be71",
secondColor: "#50be71"
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
firstColor: "#e2bd4f",
secondColor: "#e49074"
}
];
I added two properties called "firstColor" and "secondColor", to fill the LinearGradient colors, but I'm having some issues doing that. I'm receiving this error:
TypeError: undefined is not an object (evaluating '_ref3.secondColor')
Code:
const Item = ({ title }, { firstColor }, { secondColor }) => (
<LinearGradient
colors={[{firstColor}, {secondColor} ]}
style={styles.item}
>
<Text style={styles.title}>{title}</Text>
</LinearGradient>
);
const renderItem = ({ item }) => (
<Item title={item.title} />
);
...
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
Try this
const Item = ({ title, firstColor, secondColor}) => (
<LinearGradient
colors={[firstColor, secondColor ]}
style={styles.item}
>
<Text style={styles.title}>{title}</Text>
</LinearGradient>
);
const renderItem = ({ item}) => (
<Item
firstColor={item.firstColor }
secondColor={ item.secondColor }
title={item.title}
/>
);
const LinearGradient = ({ color, firstColor, secondColor }) => {
const colorArr = [firstColor, secondColor];
return (
<View>
<Text>{color}</Text>
<Text>{firstColor}</Text>
<Text>{secondColor}</Text>
</View>
);
};
can you try this, you were passing the data in the wrong way. I did some changes in similar example.
Related
I'm trying to render a flatlist that has 2 labels. I have done few options but nothing happened.
I want to show Title & Serial as Title & subtitle in each Item. If there is a solution really appreciated
Code:
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
Serial: '1254'
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Items',
Serial: '5678'
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
Serial: 'XXoX'
},
];
const Item = ({ title, Serial }) => (
<TouchableOpacity style={styles.ttListButton}>
<View style={styles.TTitem}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.title}>{Serial}</Text>
</View>
</TouchableOpacity>
);
render() {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return(
<View style={{backgroundColor: '#fff'}}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
)
there is a typo in ({ title, Seria })
should be ({ title, Serial })
const renderItem = ({ item }) => (
<Item title={item.title} Serial={item.Serial} />
);
I have the following Stack.Screen in my App.js and want to access it in another screen but don't know how to do it.
App.js file: using: { id: route.params } - When I console.log(id) it returns exactly the id. Now I would like to return the same id inside the following: <Text>Edit Screen - {id}</Text>
<Stack.Screen name='ShowScreen'
component={ShowScreen}
options={({route, navigation}) => ({
title: 'Post Details',
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('Edit', { id: route.params })}>
<AntDesign name="edit" style={styles.iconStyle} />
</TouchableOpacity>
)
})}
/>
EditScreen.js file
import React from 'react'
import { View, Text, StyleSheet } from 'react-native'
const EditScreen = ({route}) => {
const { id } = route.params
console.log(id)
return (
<View>
<Text>Edit Screen - {}</Text>
</View>
)
}
const styles = StyleSheet.create({
//
})
export default EditScreen
Here is the Solution after two days of searching:
I just add the id after the params in the app.js as follow { id: route.params.id }
<Stack.Screen name='ShowScreen'
component={ShowScreen}
options={({route, navigation}) => ({
title: 'Post Details',
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate('Edit', { id: route.params.id })}>
<AntDesign name="edit" style={styles.iconStyle} />
</TouchableOpacity>
)
})}
/>
i have a flatList that renders a component with some props, but the renderItem returns me 'undefined'. I´m new to react-native and I cant´t find a solution. Thanks
edit:
Is it possible that the styles I used in 'posts.js' may affect the flatList render?
Feed.js:
export default function Feed() {
const Posts = [
{ id: 1, title: "eu", photoDesc: 'eu' },
{ id: 2, title: "me", photoDesc: 'me' }
]
console.log;
return (
<FlatList
keyExtractor={props => props.id}
data={Posts}
renderItem={({ item }) => <FeedPosts title={`${item.title}`} photoDesc={`${item.photoDesc}`} ></FeedPosts>}
>
</FlatList>
);
}
Posts.js:
export default function FeedPosts(props) {
return (
<Container>
<Header>
<TouchableOpacity>
<FontAwesome5 name='bell' size={40} style={{ marginLeft: 10 }}></FontAwesome5>
</TouchableOpacity>
<TouchableOpacity>
<Ionicons name='add-circle' size={40} style={{ marginRight: 5 }}></Ionicons>
</TouchableOpacity>
</Header>
<Body>
<Time>15/12/2021 as 17:42pm</Time>
<User>
<Icon source={require('../../assets/vibe.jpg')}></Icon>
<Description>{props.title}</Description>
</User>
<Content>
<PetPhoto source={props.postImg}></PetPhoto>
</Content>
<ContentDesc >
<PhotoDesc> {props.photoDesc}</PhotoDesc>
</ContentDesc>
<Bottom>
<Comment title="Comment" placeholder="Escrever Comentário"></Comment>
</Bottom>
<Buttons></Buttons>
</Body>
</Container>
);
}
Your variable Posts contains an array of React components. Instead, it should contain an array of data that you transform into components.
So your Posts should look more like this:
const Posts = [
{title: "My title", photoDesc: "Desc"},
{title: "My title2", photoDesc: "Desc2"},
{title: "My title3", photoDesc: "Desc3"}
]
Here's an example (straight from the React Native documentation) of how this works in context:
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
(https://reactnative.dev/docs/flatlist)
You can see in the above example that DATA is an array of objects, which gets transformed with the function renderItem into components. Very similar to your use case.
I need a little help trying to figure this out. I am using react native elements flatlist with a checkbox inside of it. I am also using react hooks with this. Everything is working perfectly but when I try and select one of the items in the checkbox it selects all of the items. Now I have had this issue before when I was just using components and not hooks and functions. I tried to use the same method that I used here Selecting multiple items
Like this...
function ViewCategoryWS2({navigation}) {
const {category, setCategory} = useContext(ItemContext);
const [eats, setEats] = useState([]);
const [checked, toggleChecked] = useState(false);
function back() {
navigation.navigate('MenuWS2');
}
function test(index) {
const foods = category;
foods[index].checked = !foods[index].checked;
setCategory(foods);
}
return (
<View style={styles.container}>
<Icon
name='arrow-left'
color="#000000"
size={25}
style={styles.menuIcon}
onPress={back}
/>
<FlatList
data={category}
//extraData={eats}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<CheckBox
center
titleProps={{ color: 'black', fontWeight: 'bold'}}
title={item}
iconRight
checked={checked}
onPress={() => test(index)}
size={30}
containerStyle={styles.checkBox}
/>
)}
/>
</View>
)
}
and I keep getting this error TypeError: Attempted to assign to readonly property. I have also tried it this way...
<FlatList
data={category}
//extraData={eats}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<CheckBox
center
titleProps={{ color: 'black', fontWeight: 'bold'}}
title={item}
iconRight
checked={checked}
onPress={() => toggleChecked(!checked)}
size={30}
containerStyle={styles.checkBox}
/>
)}
/>
Here is my code from where the context is coming from. This page I pull data from my datbase and it displays categories. I click on any category and it pulls data from my database that's assigned to that certain category that was clicked on..
Here is the code...
import ItemContext from '../context/CategoryItems';
export default function menuWS({navigation}) {
const [restaurantlocationcode, setRestaurantlocationcode] = useState('')
const [menu, setMenu] = useState([]);
const {category, setCategory} = useContext(ItemContext);
const [selected, setSelected] = useState(0);
function viewMenu() {
fetch('URL', {
method: 'POST',
body: JSON.stringify({ restaurantlocationcode: restaurantlocationcode}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(response=> setMenu(response));
console.log(menu);
alert(menu);
}
function viewCategory({item}) {
fetch('URL', {
method: 'POST',
body: JSON.stringify({
category: item,
restaurantlocationcode: restaurantlocationcode,
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(response => {
setCategory(response);
console.log(response);
alert(response);
});
navigation.navigate('ViewCategoryWS2', {category});
}
function showMenu() {
console.log(menu);
alert(menu);
}
const buttons = ['Menu']
return (
<View style={styles.container}>
<Input
style={styles.Input}
placeholder='Restaurant Location Code'
leftIcon={
<Icon
name='location-arrow'
size={24}
color='black'
/>
}
onChangeText={setRestaurantlocationcode}
value={restaurantlocationcode}
underlineColorAndroid='transparent'
/>
<ButtonGroup
onPress={viewMenu}
selectedIndex={selected}
selectedButtonStyle={{backgroundColor: 'blue'}}
buttons={buttons}
containerStyle={styles.buttonGroup}
/>
<FlatList
data={menu}
extraData={category}
keyExtractor={(item, index) => index.toString()}
renderItem={({item, index}) => (
<ListItem
titleStyle={{ color: 'black', fontWeight: 'bold'}}
title={item}
onPress={() => viewCategory({item})}
bottomDivider
chevron
/>
)}
/>
</View>
)
}
Here is my useContext code...
import { createContext } from 'react';
const ItemContext = createContext({});
export default ItemContext;
Here is the second part to my useContext code..
import React, {useState} from 'react';
import ItemContext from './CategoryItems';
const MenuItemState = ({children}) => {
const [category, setCategory] = useState([]);
return (
<ItemContext.Provider value={{category, setCategory}}>
{children}
</ItemContext.Provider>
)
}
export default MenuItemState;
And it just selects all of the items. I'm not sure what I am missing. Help with this would be greatly appreciated.
App Output:
import React, { useState } from 'react';
import { Text, View, StyleSheet, CheckBox, Icon, FlatList } from 'react-native';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
/*
I am using this data, but you can continue
with the one you getting from context
*/
const data = [
{ id: 1, title: 'one', checked: true },
{ id: 2, title: 'two', checked: false },
{ id: 3, title: 'three', checked: false },
{ id: 4, title: 'four', checked: false },
{ id: 5, title: 'five', checked: false },
{ id: 6, title: 'six', checked: false },
];
export default function App() {
const [category, setCategory] = useState(data);
const [eats, setEats] = useState([]);
const [checked, toggleChecked] = useState(false);
function back() {
// navigation.navigate('MenuWS2');
}
function test(index) {
/*
Use this approach while changing the state.
This will create the copy of original array,
and you can perform mutation there
and update state with it.
*/
console.log(index);
const foods = [...category];
foods[index].checked = !foods[index].checked;
setCategory(foods);
}
/*
In your Checkbox component,
use "onChange" prop instead of "onPress"
and "value" instead of "checked"
*/
return (
<View style={styles.container}>
<FlatList
data={category}
//extraData={eats}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<Card style={{ padding: 10, margin: 5 }}>
<Text>{item.title}</Text>
<CheckBox
center
titleProps={{ color: 'black', fontWeight: 'bold' }}
title={item}
iconRight
value={item?.checked}
onChange={() => test(index)}
size={30}
containerStyle={styles.checkBox}
/>
</Card>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
marginTop: 24,
backgroundColor: 'grey',
flex: 1,
},
});
Working Example: Expo Snack
My question is somewhat unique than many other similar ones: I want to pass some list to another screen through a (functional) component. It doesn't work.
App.js has:
const switchNavigator = createSwitchNavigator({
locationAllFlow: createStackNavigator(
{
locationsFlow: createStackNavigator(
{
Locations: { screen: LocationsScreen },
Search: { screen: SearchScreen }
},
{
headerMode: 'none'
}
),
LocationDetail: LocationDetailScreen
},
{
headerMode: 'none'
}
),
...
Then LocationsScreen has:
<TitleBar
title='Locations'
hasSearch={true}
list={results.map(result => result.name)}
/>
and LocationsScreen has TitlBar as a component:
const TitleBar = ({ navigation, title, hasSearch, list }) => {
...
<TouchableOpacity
style={{ padding: 8, position: 'absolute', right: 4 }}
onPress={() => {
console.log('inside onPress: ', list);
navigation.navigate('Search', { list });
}}
>
<MaterialIcons style={styles.titleIcon} name='search' />
</TouchableOpacity>
...
export default withNavigation(TitleBar);
and finally, need to go to SearchScreen:
const SearchScreen = ({ list }) => {
console.log('SearchScreen: list.length: ', list);
return (
<View style={{ backgroundColor: 'rgb(15, 104, 186)', flex: 1 }}>
<SafeAreaView>
<FlatList
data={list}
keyExtractor={item => item}
renderItem={({ item }) => (
<TouchableOpacity>
<Text>item</Text>
</TouchableOpacity>
)}
/>
</SafeAreaView>
</View>
);
};
Trouble happens in the SearchScreen: though inside onPress: prints list very well, somehow, SearchScreen: list.length: prints undefined. Why?
list won't be passed as params to SearchScreen. You should use navigation.getParam(paramID, defaultValue) instead
Docs reference: https://reactnavigation.org/docs/en/params.html