FlatList doesn't render with React Hooks - reactjs

I am trying to rename [0]items in FlatList by clicking some item, But it doesn't work for me, when i click on each item nothing happen and i don't get any error. How can i fix this?
This is my code.
export default function renameSample() {
const data = [
{
id: '1',
name: 'test1',
},
{
id: '2',
name: 'test2',
},
{
id: '3',
name: 'test3',
},
];
const [stateUser, onChangeUser] = useState(data);
return (
<FlatList
data={stateUser}
renderItem={({item}) =>
<TouchableOpacity
onPress={() => {
let setData = stateUser;
setData[0].name = 'changed';
onChangeUser(setData);
}
}
>
<Item name={item.name} />
</TouchableOpacity>
}
keyExtractor={item => item.id}
/>
</View>
);
}

If your requirement is to change the clicked item, the code would be like below.
You can get the index of the clicked item and change it.
function RenameSample() {
const data = [
{
id: '1',
name: 'test1',
},
{
id: '2',
name: 'test2',
},
{
id: '3',
name: 'test3',
},
];
const [stateUser, onChangeUser] = useState(data);
return (
<View>
<FlatList
data={stateUser}
renderItem={({ item, index }) => (
<TouchableOpacity
onPress={() => {
const newData=[...stateUser];
newData[index].name = 'changed';
onChangeUser(newData);
}}>
<Item name={item.name} />
</TouchableOpacity>
)}
keyExtractor={(item) => item.id}
/>
</View>
);
}

Related

Get data from an array to create dynamically <Text> component react-native

I got array:
const DATA_Section = [
{
id: 0,
text: "Some text1",
},
{
id: 1,
text: "Some text2",
},
{
id: 2,
text: "Some text 3",
},
];
and I want to use text from this array to create dynamic component. Idea is: I can see text[0], I click some button then I can see text[1], something like loop. How can to do it?
You can do this way maybe.
const DATA_Section = [
{
id: 0,
text: "Some text1",
},
{
id: 1,
text: "Some text2",
},
{
id: 2,
text: "Some text 3",
},
];
const Component: FC = () => {
const [initialRenderState, setInitialRenderState] =
useState(DATA_Section[0])
return (
<View>
{intialRenderState.map(item => <Text key={item.id}>{item.text}</Text>)}
<Pressable onPress={()=> setInitialRenderState(prevState => [...prevState, Data_Section[prevState.length]])}>
<Text>Add item</Text>
<Pressable>
</View>
)
}
const DATA_Section = [
{
id: 0,
text: "Some text1",
},
{
id: 1,
text: "Some text2",
},
{
id: 2,
text: "Some text 3",
},
];
const sample = () => {
const [ index, setIndex ] = useState(0);
const handleChangeIndex = () => {
if (index < DATA_Section.length) {
setIndex(index + 1);
}else{
setIndex(0);
}
}
return(
<View style={{flex:1}}>
<TouchableWithoutFeedback onPress={()=>handleChangeIndex()}>
<View style={{width:100, height:50, backgroundColor:'red'}}>
<Text>
{DATA_Section[index].text}
</Text>
</View>
</TouchableWithoutFeedback>
</View>
);
}

React Native Flatlist is not rendering any item in the list on screen with renderItem

I have a react component that is supposed to render a list of values based on an array of objects that I have stored.
It is not rendering any of the items on the screen and I am not sure why. I looked at the docs and other references and it is not giving me a solution. I have a feeling it is simple but I have coders block.
Here is my code:
this is the object I am trying to render:
const bedCount = [{
value: null,
label: 'Any',
key: 7
},
{
value: 0,
label: 'Studio',
key: 0
},
{
value: 1,
label: '1',
key: 1
},
{
value: 2,
label: '2',
key: 2
},
{
value: 3,
label: '3',
key: 3
},
{
value: 4,
label: '4',
key: 4
},
{
value: 5,
label: '5',
key: 5
},
{
value: 6,
label: '6',
key: 6
}]
Here is the flat list
<View>
<Text>
Min. Beds:
</Text>
<FlatList
data={bedCount}
horizontal={true}
keyExtractor={item => item.key}
renderItem={(item) => {
<TouchableOpacity onPress={setMinBeds(item.value)}>
<Text>{item.label}</Text>
</TouchableOpacity>
}}
/>
</View>
This is what is rendering on screen:
<View>
<Text>
Min. Beds:
</Text>
<FlatList
data={bedCount}
horizontal={true}
keyExtractor={item => item.key}
renderItem={(item) => (
<TouchableOpacity onPress={setMinBeds(item.value)}>
<Text>{item.label}</Text>
</TouchableOpacity>
)}
/>
</View>
You need to return an element using bracket () instead of {}

How to print multiple datas in FlatList

export default class App extends Component {
constructor() {
super();
// flatlist data
this.state = {
data: [
{ key: "Skptricks", data: "one", name: "one" },
{ key: "Sumit" , data: "two" , name: "one"},
{ key: "Amit" , data: "three", name: "one"},
],
}
}
// flat list
render() {
return (
<View>
<FlatList
data={this.state.data}
renderItem={({item}) => <Text>{item.name}</Text>
/>
</View>
);
}
}
Can you explain what exactly do you need to print ? Please refer the code. I'm printing the 'name' item of your array. If you want to print 'data' items , use item.data inside renderItem. Let me know if you need any help.
const DATA = [{ key: "Skptricks", data: "one", name: "one" },
{ key: "Sumit" , data: "two" , name: "one"},
{ key: "Amit" , data: "three", name: "one"},
];
const Item = ({ name }) => (
<View style={styles.item}>
<Text style={styles.name}>{name}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item name={item.name} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight || 0,
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
name: {
fontSize: 32,
},
});

Minimizing un-necessary re-renders in a large list React component tree

I am creating a large list with this accordion on React Native. The problem I face is the re-renders that happening in the renderItem function. When the input changes in the Product component whole component tree is re-rendered. Is there way to stop re-rendering the whole component tree for input changes on the product component with using React.memo or React.useMemo ?
const categories = [
{ id: 1, name: 'Category A' },
{ id: 2, name: 'Category B' },
{ id: 3, name: 'Category B' },
]
const products = [
{ id: 1, name: 'Product A', category: 1 },
{ id: 2, name: 'Product B', category: 1 },
{ id: 3, name: 'Product C', category: 2 },
{ id: 4, name: 'Product D', category: 2 },
{ id: 5, name: 'Product E', category: 3 },
]
const handleChange = (product, quantity) => {
console.log('handle change event fired');
};
const renderHeader = (category) => {
return (
<View>
<Text>{category.name}</Text>
</View>
);
};
const renderContent = (category) => {
const categoryProducts = products.filter(product => product.category_id === category.id);
const renderItem = (product) => {
return (
<Product
key={product.id}
product={product}
handleChange={handleChange}
/>
);
};
return (
<View>
{
categoryProducts.map(product => {
return (renderItem(product));
})
}
</View>
);
};
return (
<ScrollView>
<Accordion
sections={categories}
renderHeader={renderHeader}
renderContent={renderContent}
/>
</ScrollView>
);
The Product Compoenent
<View>
<Input
size="small"
keyboardType="number-pad"
onChangeText={(changedQuantity) => {
handleChange( product, changedQuantity);
}}
value={quantity}
/>
</View>

Issues mapping within a map - React Native

The app I'm making develops the following array format to store user input:
[
{name: Bob,
id: 1,
sports: [{sport: Baseball,
id: 1
},
{sport: Basketball,
id: 2
}]
},
{name: James,
id: 2,
sports: [{sport: Hockey,
id: 3
},
{sport: Soccer,
id: 4
}]
}
]
I am trying to render this to effectively get the following output:
<Text>Bob</Text>
<Text>Baseball</Text>
<Text>Basketball</Text>
<Text>James</Text>
<Text>Hockey</Text>
<Text>Soccer</Text>
I would of thought I could achieve this by mapping within a map eg:
{Array.map((item) => {
return(
<Text>{item.name}</Text>
{item.sports.map((item2) => {
return(
<Text>{item2.sport}</Text>
)
})
)
})}
but can't get anything like this to work. I can console.log the results I want with:
const display = Array.map(item => {
return console.log(item.name, item.sports.map(item2 => {
return item2.sport}))
})
But I guess I don't know how to render this out?
You have a lot of errors in the code or is it a neglect of responders.
const userInput = [
{
name: "Bob",
id: 1,
sports: [
{ sport: "Baseball", id: 1 },
{ sport: "Basketball", id: 2 },
],
},
{
name: "James",
id: 2,
sports: [
{ sport: "Hockey", id: 3 },
{ sport: "Soccer", id: 4 },
],
},
];
{userInput.map((user) => (
<>
<Text>{user.name}</Text>
{user.sports.map((s) => (
<Text>{s.sport}</Text>
))}
</>
))}
Ok so I just found out what I was doing wrong haha. I need to have the content from my first map and the second map function encased in one View. Eg:
const display = Array.map(item => {
return (
<View> <------------------------I didn't have these originally
<View>
<Text>
{item.name}
</Text>
</View>
{item.sports.map(item2 => {
console.log(item2)
return (
<View>
<Text>
{item2.sport}
</Text>
</View>
)
})}
</View> <------------------------I didn't have these originally
)
})

Resources