Flatlist inside a function in react native - react-native

How can I create an flatlist and add items to it inside a function not a class in react native?? all of the examples online are using classes and I need to use it inside a function !!

I found an example of a FlatList in the React Native docs that is using a functional component:
https://reactnative.dev/docs/flatlist
If you just want the code check out the same example on snack:
https://snack.expo.io/?session_id=snack-session-R6Nsz_Qm1&preview=true&platform=web&iframeId=uetjvvask3&supportedPlatforms=ios,android,web&name=flatlist-simple&description=Example%20usage&waitForData=true
I hope it helped :)

Same as with any other component, there's not much difference between using a FlatList inside a class vs a function. Only the state handling changes a little bit.
The code below will render all items, you'll be able to press on any of them to duplicate the item which should then show up at the bottom of the list.
export const FlatListScreen = props => {
const [items, setItems] = useState([1, 2, 3, 4, 5]);
function duplicateItem(toDuplicate) {
setItems(prev => [...prev, toDuplicate]);
}
return (
<FlatList
data={items}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={() => duplicateItem(item)}>
<View>
<Text>
{item}
</Text>
</View>
</TouchableWithoutFeedback>
)}
/>
);
}

Related

react native textinput lost focus after 1 char type

I have this problem with ios but not with android. It only disturb the add task input the task edit and the list name edit. The input addList(It's the one with "What to do?" on the draw) in the header works fine.
UI drawing
Achitecture of components
I console log my component and I can see it rerender everytime I add a letter in the input field.
I checked on google and follow this:(can we link other website here?) https://www.codegrepper.com/code-examples/javascript/react+native+textinput+lost+focus+after+charter+type
Tried the the first solution with onBlurr and onFocus.
I tried to make a TextInput component for add task.
I even try with my component addList but it didn't solve the problem.
Anyone have faced this problem before? Is there anyway to by pass this?
My code without the import/style look like this:
const TaskList: FunctionComponent<TasksListProps> = ({
addTask,
deleteTask,
toggleTask,
editTaskName,
...props
}) => {
console.log('props', props);
const [nameOfTask, setNameOfTask] = useState('');
console.log('name', nameOfTask);
const textHandler = (enteredName: string) => {
setNameOfTask(enteredName);
};
const handleSubmitTask = () => {
if (nameOfTask === '') {
return;
}
addTask(props.listId, nameOfTask);
setNameOfTask('');
};
return (
<View style={styles.tasksListContainer}>
{props.tasks.map(task => (
<SingleTask
key={task.id}
task={task}
listId={props.listId}
deleteTask={deleteTask}
toggleTask={toggleTask}
editTaskName={editTaskName}
/>
))}
<View style={styles.taskInputContainer}>
<TextInput
style={styles.tasksTextInput}
value={nameOfTask}
onChangeText={textHandler}
placeholder="Write a task to do"
/>
<TouchableOpacity onPress={handleSubmitTask}>
<Image source={require('./Img/add-button.png')} />
</TouchableOpacity>
</View>
</View>
);
};
You can create a HOC and wrap your screen width DismissKeyboard
import { Keyboard } from 'react-native';
const DismissKeyboard = ({ children }) => (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
{children}
</TouchableWithoutFeedback>
);
That because Re render.
Try to make the input with the main component of the page to test it.
Then check where the error with re-render

React native move flatlist from one screen to another

I have already done firebase with user authentication. Each result is displayed in a flatlist. Upon clicking the heart icon I want to move the selected item to the favorite screen.
Home Screen
<FlatList
contentContainerStyle={ { alignSelf:"center",}}
data={Results}
keyExtractor={(Result) => Result.id.toString()}
renderItem={({ item }) => {
// console.log(item.id);
return (
<TouchableOpacity
onPress={() => {
navigation.navigate("ResultsShowScreen", {
id: item.id,
image: item.image,
});
}}
>
<ResultsDetail Result={item} />
</TouchableOpacity>
);
}}
/>
</View>
Favorites Screen
<View>
<Text> Screen</Text>
</View>
You can achieve this by reading the properties of the route.params object of your Favorite Screen. Like so:
function Favorites ({route}) {
const {id, image} = route.params;
return (
...
);
}
Keep in mind that this will only show the id and image you are passing when the TouchableOpacity is pressed. If you want a list of all the favorites, you need to store them on a data structure like an array (and modify the array when an item is faved/unfaved), and pass that array to the Favorite Screen
For the complete reference of this feature, you can read the Passing parameters to routes page of React Navigation docs.

OnPress change the style of component from loop- React Native with hooks

So I am pretty new in react native, I am trying to develop a quiz game, where users will be given Set of answers. I want to select change the color of the component when it is pressed by the user, kind of toggle it. So far I came up with useState solution, but unfortunately cannot figure out how to exclude the change of color, I guess I need to follow indexing or something, can anyone please make me understand the process with the solution.
export const QuizScreen = ({ navigation,route }) => {
const [quizArray, setQuizArray] = React.useState([])
const [rightAnswer, setRightAnswer]= React.useState(false)
const [selectBtn, setSelectBtn] = React.useState("#fff")
return(
<View>
{quizArray[qno].answer.map(r=>
<TouchableHighlight style={[styles.listItem, {backgroundColor:selectBtn}]}
onPress={()=>{
setRightAnswer(r.rightAnswer)
setSelectBtn("#DDDDDD") //so this changes logically all the component from the list
}}
activeOpacity={0.6} underlayColor="#DDDDDD"
>
<Text>{r.option}</Text>
</TouchableHighlight>
)}
</View>
I need to know how do i implement the background change for only one and kinda make it toggle everytime user select or deselect. Thank you
You were right about using an index for determining the clicked list item.
You can change the color by storing the index of the selected item using selectBtn state and then using that state set the backgroundColor accordingly.
Here is how you can do it:
export const QuizScreen = ({ navigation, route }) => {
const [quizArray, setQuizArray] = React.useState([]);
const [rightAnswer, setRightAnswer] = React.useState(false);
const [selectBtn, setSelectBtn] = React.useState(null);
return (
<View>
{quizArray[qno].answer.map((r, index) => (
<TouchableHighlight
style={[
styles.listItem,
{ backgroundColor: selectBtn === index ? '#dddddd' : '#fff' },
]}
onPress={() => {
setRightAnswer(r.rightAnswer);
setSelectBtn(index);
}}
activeOpacity={0.6}
underlayColor="#DDDDDD">
<Text>{r.option}</Text>
</TouchableHighlight>
))}
</View>
);
};
Here is the working example: Expo Snack
2

How can I use a state in a FlatList?

I have a FlatList and I want to show a number like quantity of product. So I use a state for that. Now when I press on TouchableOpacity to change quantity to 1 working fine in console, but I can't see any change in FlatList.
constructor(props){
super(props);
this.state={
quantity : 0,
}
Increment quantity:
incrementCount=()=>{
if(this.state.quantity != 10){
console.log(this.state.quantity);
this.setState((prevState, props) => ({
quantity: this.state.quantity + 1,
}));
}
}
FlatList:
<FlatList
data={this.state.dataSource}
renderItem={({item}) =>
<View>
<Text>{item.title}</Text>
<Text>{this.state.quantity}</Text>
<TouchableOpacity onPress={this.incrementCount} activeOpacity={0.5}>
<AntDesign name="plus" size={15}/>
</TouchableOpacity>
</View>
}
/>
Listview is deprecated now use Flatlist instead of this.
Refer this official doc for more information react-native listview
This is the common problem about pre-increment vs post-increment in javascript (you can read more about this here: ++someVariable Vs. someVariable++ in Javascript )
You can solve this problem by simply incrementing the variable before the setState:
const quantity = this.state.quantity + 1;
this.setState({ quantity }) // this is ES6 syntax
Anyway, you should not use ListView because it's deprecated. ( https://facebook.github.io/react-native/docs/listview.html )
There are other components:
FlatList ( https://facebook.github.io/react-native/docs/flatlist )
SectionList ( https://facebook.github.io/react-native/docs/sectionlist )
VirtualizedList ( https://facebook.github.io/react-native/docs/virtualizedlist )

React Native, Passing Navigation to Stateless Flatlist component

Currently I have:
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={(data) => <EventCard eventinfo = {data.item} navigation=
{this.props.navigation}/>}
keyExtractor={(item) => item.eventname}
/>
and
const EventCard = ({eventinfo, navigation}) => {
return (
<TouchableOpacity style={{backgroundColor: 'transparent'}} onPress= {()
=> navigation.navigate('CurrRes')}>
I dont understand why Navigation cant be evaluated in my Eventcard, and navigation doesnt work. Any help would be appreciated.
(yes withnavigation is imported in the first file and the project runs but crashes when one of the flatlist items is pressed)
The error i get is
undefined is not an object (evaluating 'navigation.navigate')
Here is an example I found to explain it better.
You need to access props differently than just a normal function with deconstruction.
const Child = (props) => {
return (
<div style={{backgroundColor: props.eyeColor}} />
)
}
https://medium.com/#PhilipAndrews/react-how-to-access-props-in-a-functional-component-6bd4200b9e0b
Nevermind, I had to export the actual list with navigation so each of its nested stateless components could navigate. Sorry!