I'm new to react-native and react at all. So i decided to start with simple todo app, but stuck with problem. I moved FlatList, RenderItem method and other methods to deal with tasks list into standalone component. This component imports to HomeScreen, which also store array with all task (this array passes to ItemList as prop). Everything work as i expect, task's view updates if state changes, there deleting from list. But if i want to add task parameters passing by react navigation from another screen to HomeScreen.
tl;dr: array stores in 1st component and this array passes to 2nd component, how to update array and re-render changes.
ItemList.jsx:
import React, { useState } from 'react'
import { FlatList } from 'react-native-gesture-handler'
import { Text } from 'react-native'
import Item from './Item'
const ItemList = (props) => {
const [taskList, setTaskList] = useState([...props.list])
const itemRender = ({ item }) => {
// checkbox handler function
const checkBoxHandler = (isChecked) => {
// set Task's isDone state
let elem = taskList.find(x => x.id === item.id)
elem.isDone = isChecked
// removing & pushing elem
let _taskList = taskList.filter(x => x.id !== elem.id)
isChecked ? _taskList.push(elem) : _taskList.unshift(elem)
console.debug(_taskList)
// call hook
setTaskList(_taskList)
}
// function to count time until deadline
// and return Text element
const calculateDeadline = () => {
var deltaTime = item.expireDate - new Date()
var deltaDays = Math.ceil(deltaTime / (1000 * 60 * 60 * 24))
if (!item.isDone) {
if (0 < deltaDays && deltaDays <= 7)
return <Text>Deadline in {deltaDays} days</Text>
else if (deltaDays == 0)
return <Text>Deadline today!</Text>
else if (deltaDays < 0)
return <Text style={{ color: 'red' }}>Overdue</Text>
}
return null
}
const deleteHandler = () => {
let _taskList = taskList.filter(x => x.id !== item.id)
console.debug(_taskList)
setTaskList(_taskList)
}
return (
<Item
title={item.title}
desc={item.desc}
checkBoxHandler={checkBoxHandler}
calculateDeadline={calculateDeadline}
deleteHandler={deleteHandler}
isDone={item.isDone}
/>
)
}
const onRefresh = () => {
setTaskList(taskList)
}
return (
<FlatList
data={taskList}
renderItem={itemRender}
keyExtractor={item => item.id}
onRefresh={onRefresh}
/>
)
}
export default ItemList
HomeScreen.jsx:
import React, { useEffect } from 'react'
import {
SafeAreaView,
StyleSheet,
StatusBar
} from 'react-native'
import Task from '../Components/modelItem'
import ItemList from '../Components/ItemList'
import FloatButton from '../Components/FloatButton'
const HomeScreen = ({ navigation, route }) => {
const taskList = [
new Task(1, 'example', 'some example task', new Date(),
new Date("2021-10-21")),
new Task(2, 'RN TODO', 'create todo app', new Date(),
new Date("2021-11-18")),
new Task(3, 'something', 'do something', new Date(),
new Date("2021-11-25")),
]
console.log(route.params)
useEffect(() => {
if (route.params?.description) {
console.log('useEffect:')
console.log(route.params)
taskList.push(new Task(null, 'test task', route.params.description,
route.params.creationDate, route.params.expireDate))
}
}, [route.params?.description])
return (
<SafeAreaView style={styles}>
<ItemList
list={taskList}
/>
<FloatButton onPress={() => navigation.navigate('AddNewTask')} />
</SafeAreaView>
)
}
const styles = StyleSheet.create({
flex: 1,
marginTop: StatusBar.currentHeight || 0,
})
export default HomeScreen
taskList.push won't cause an rerender.
Your tasklist should be managed by useState.
Change:
const taskList = [
new Task(1, 'example', 'some example task', new Date(),
new Date("2021-10-21")),
new Task(2, 'RN TODO', 'create todo app', new Date(),
new Date("2021-11-18")),
new Task(3, 'something', 'do something', new Date(),
new Date("2021-11-25")),
]
To:
const [taskList, setTaskList] = useState([
new Task(1, 'example', 'some example task', new Date(),
new Date("2021-10-21")),
new Task(2, 'RN TODO', 'create todo app', new Date(),
new Date("2021-11-18")),
new Task(3, 'something', 'do something', new Date(),
new Date("2021-11-25")),
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.