嗨,我正在嘗試通過單擊“完成”圖示將任務標記為已完成,因此它會貫穿文本。我已經完成了一個 foreach 回圈來查找具有相同 ID 的專案,因此我可以更改其狀態以根據它更改樣式,但沒有任何反應。我肯定錯過了一些東西,我對此很陌生。單擊該圖示后,我添加了控制臺日志以查看狀態并且不會更改。
這是我的任務項
import React from 'react'
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native'
import { MaterialIcons } from '@expo/vector-icons'
const TaskItem = (props) => {
return (
<View style={styles.container}>
<View style={styles.indexContainer}>
<Text style={styles.index}>{props.index}</Text>
</View>
<View style={styles.taskContainer}>
<Text style={(props.status) ? styles.taskDone : styles.task}>{props.task}</Text>
<TouchableOpacity onPress={() => props.deleteTask()}>
<MaterialIcons
style={styles.delete}
name="delete"
size={18}
color="#fff"
/>
</TouchableOpacity>
<TouchableOpacity onPress={() => props.markTaskDone(props.id)}>
<MaterialIcons
style={styles.done}
name="done"
size={18}
color="#fff"
/>
</TouchableOpacity>
</View>
</View>
)
}
export default TaskItem
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 20,
},
indexContainer: {
backgroundColor: '#CEAA9A',
borderRadius: 12,
marginRight: 10,
alignItems: 'center',
justifyContent: 'center',
width: 50,
height: 50,
},
index: {
color: '#fff',
fontSize: 20,
},
taskContainer: {
backgroundColor: '#CEAA9A',
borderRadius: 12,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
flex: 1,
paddingHorizontal: 10,
paddingVertical: 5,
minHeight: 50,
},
task: {
color: '#fff',
width: '90%',
fontSize: 16,
},
taskDone: {
color: '#fff',
width: '90%',
fontSize: 16,
textDecorationLine: "line-through",
},
delete: {
marginLeft: 0,
},
done: {
marginLeft: 0,
},
})
這是我的 App.js
import { Keyboard, ScrollView, StyleSheet, Text, View } from 'react-native';
import TaskInputField from './components/TaskInputField';
import TaskItem from './components/TaskItem';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function App() {
const [tasks, setTasks] = useState([]);
const [ appInit, setAppInit ] = useState( true )
useEffect( () => {
if( appInit ) {
getData()
setAppInit( false )
console.log('getting data...')
}
else {
storeData()
console.log('storing data...')
}
// sortData()
}, [tasks] )
const addTask = (task) => {
if (task == null) return;
const id = new Date().getTime().toString()
task = { id: id, name: task, status: false }
setTasks([...tasks, task]);
//console.log(tasks)
//console.log(task)
//console.log(item)
Keyboard.dismiss();
}
const deleteTask = (deleteIndex) => {
setTasks(tasks.filter((value, index) => index != deleteIndex));
}
const markTaskDone = (id) => {
let items = [...tasks]
items.forEach( (task) => {
if( task.id === id ) {
task.status = true }
})
//console.log(id)
//setTasks( task)
}
const storeData = async () => {
const stringified = JSON.stringify( tasks )
try {
await AsyncStorage.setItem( "listData" , stringified )
} catch (error) {
console.log( error )
}
}
const getData = async () => {
try {
const stringified = await AsyncStorage.getItem("listData")
setTasks( (stringified !== null) ? JSON.parse(stringified) : [] )
} catch (error) {
console.log( error )
}
}
return (
<View style={styles.container}>
<Text style={styles.heading}>TODO LIST</Text>
<ScrollView style={styles.scrollView}>
{
tasks.map((task, index) => {
return (
<View key={index} style={styles.taskContainer}>
<TaskItem index={index 1} task={task.name} deleteTask={() => deleteTask(index)} markTaskDone={() => markTaskDone()}/>
</View>
);
})
}
</ScrollView>
<TaskInputField addTask={addTask}/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f4ef',
},
heading: {
color: '#CEAA9A',
fontSize: 20,
fontWeight: '600',
marginTop: 30,
marginBottom: 10,
marginLeft: 20,
},
scrollView: {
marginBottom: 70,
},
taskContainer: {
marginTop: 20,
}
});
謝謝
uj5u.com熱心網友回復:
ForEach 只是回圈陣列并在每個專案上呼叫回呼函式,map 回傳由回呼函式更改的新陣列
const markTaskDone = (id) => {
const newItems = tasks.map( (task) => {
if( task.id === id ) {
task.status = true }
})
//console.log(id)
setTasks( newItems )
}
uj5u.com熱心網友回復:
你的問題在這里:
const markTaskDone = (id) => {
let items = [...tasks]
items.forEach( (task) => {
if( task.id === id ) {
task.status = true }
})
//console.log(id)
//setTasks( task)
}
在forEach不修改該陣列。嘗試這樣映射:
const markTaskDone = (id) => {
/*
here I pass a function to setTasks as I found that with arrays
that if you use the current value of the state (tasks), that
sometimes unexpected results happen.
*/
setTasks(prev=>prev.map( (task) => {
if( task.id === id ) {
task.status = true
}
return task
})
// setting task traditionally
setTasks(tasks.map(task=> {
if( task.id === id ) {
task.status = true
}
return task
}) ))
//console.log(id)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/333515.html
上一篇:型別錯誤:無法讀取未定義的屬性(讀取“setState”)
下一篇:R檢查多個條件并從列轉換為行
