javascript - 在 React Native 中向父级传递值
问题描述
待办事项清单
我有一个useState
名为任务(数组)的父母。
对于数组中的每个项目(任务),我正在显示一个带有项目数据和删除按钮的组件。
现在每个组件(子)都有一个删除按钮。但是带有任务的数组位于父类中,因此我无法删除任务或该组件,因为按钮位于组件(子)内部。
这个问题有什么解决方案吗?
注意:我试图找到解决方案,但似乎找不到。所以只要告诉我该怎么做,整个代码就在这里。
需要帮助的部分有注释
家长:
import React, { useState, useEffect } from "react";
import {
Keyboard,
KeyboardAvoidingView,
Platform,
ScrollView,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import Task from "./components/Task";
export default function App() {
const [tasks, setTasks] = useState([]);
const [newTask, setNewTask] = useState();
const AddTask = () => {
Keyboard.dismiss();
if (newTask == null) return;
setTasks([...tasks, { name: newTask }]);
setNewTask(null);
};
const removeTodo = (index) => {
let CopyLi = [...tasks];
CopyLi.splice(index, 1);
setTasks(CopyLi);
};
return (
<View style={styles.container}>
<View style={styles.taskWrapper}>
<Text style={styles.sectionTitle}>Today's task</Text>
<ScrollView style={styles.items}>
{/* Here is the Rendering of Child Component */}
{tasks.map((item, index) => {
return <Task key={index} text={item.name} />;
})}
</ScrollView>
</View>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.inputWrapper}
>
<TextInput
style={styles.input}
placeholder={"Add a new Task"}
value={newTask}
onChangeText={(text) => setNewTask(text)}
/>
<TouchableOpacity onPress={() => AddTask()}>
<View style={styles.btnWrapper}>
<Text style={styles.btnIcon}>+</Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#e8eaed",
},
taskWrapper: {
paddingTop: 80,
},
sectionTitle: {
fontSize: 24,
fontWeight: "bold",
marginHorizontal: 20,
},
items: {
marginTop: 30,
height: "78%",
},
inputWrapper: {
width: "100%",
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center",
height: 100,
},
input: {
paddingVertical: 15,
paddingHorizontal: 20,
backgroundColor: "#fff",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
width: "70%",
},
btnWrapper: {
width: 60,
height: 60,
backgroundColor: "#fff",
borderRadius: 60,
borderColor: "#C0C0C0",
borderWidth: 1,
alignItems: "center",
justifyContent: "center",
},
btnIcon: {
fontSize: 30,
transform: [{ translateY: -2 }],
color: "#A4A4A4",
},
});
孩子:
import React, { useState } from "react";
import {
View,
Text,
StyleSheet,
CheckBox,
TouchableOpacity,
} from "react-native";
const Task = (props) => {
const [toggle, setToggle] = useState(false);
return (
<View style={styles.item}>
<View style={styles.itemLeft}>
<CheckBox
value={toggle}
onValueChange={setToggle}
style={[{ textDecorationLine: "line-through" }, styles.square]}
/>
<Text
style={[styles.itemText, toggle ? styles.checked : styles.unchecked]}
>
{props.text}
</Text>
</View>
<TouchableOpacity style={styles.itemRight}></TouchableOpacity>
{/*Here is the Button/TouchableOpacity to delete this component */}
</View>
);
};
const styles = StyleSheet.create({
item: {
backgroundColor: "#fff",
padding: 15,
borderRadius: 10,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginBottom: 20,
width: "90%",
alignSelf: "center",
},
itemLeft: {
flexDirection: "row",
alignItems: "center",
flexWrap: "wrap",
},
square: {
marginRight: 10,
transform: [{ scaleX: 1.2 }, { scaleY: 1.2 }],
},
itemText: {
maxWidth: "80%",
fontSize: 16,
},
checked: { textDecorationLine: "line-through" },
unchecked: { textDecorationLine: "none" },
itemRight: {
width: 15,
height: 15,
borderColor: "#f94355",
borderWidth: 2,
borderRadius: 10,
backgroundColor: "#ff2848",
},
});
export default Task;
解决方案
首先在父组件中创建remove函数,并传递给子组件,然后在子组件中使用remove函数并传递索引。例如,您的代码如下所示:
import React from 'react';
function Todo({ todo, index, removeTodo }) {
return (
<div className="todo">
<span>{todo.text}</span>
<button onClick={() => removeTodo(index)}>Delete</button>
</div>
);
};
function App() {
const [todos, setTodos] = React.useState([
{ text: "Learn about React" },
{ text: "Meet friend for lunch" },
{ text: "Build really cool todo app" }
]);
const removeTodo = (index) => {
let todosArrCopy = [...todos];
todosArrCopy.splice(index,1);
setTodos(todosArrCopy);
}
return (
<div className="app">
<div className="todo-list">
{todos.map((todo, index) => (
<Todo
key={index}
index={index}
todo={todo}
removeTodo={removeTodo}
/>
))}
</div>
</div>
);
}
export default App;
推荐阅读
- java - 从网络读取 xml
- automated-tests - 自动化测试的代码覆盖率
- excel - Excel VBA切片器选择每个项目
- python - 检查列表是否存在于列表列表中的最快方法
- laravel - Laravel - 雄辩:在模型中准备插入方法
- python - load_csv_with_header() 得到了一个意外的关键字参数“target_dytpe”
- node.js - 在我的 .babelrc 文件中添加插件的正确位置在哪里
- reactjs - 在测试 React 组件时,Enzyme 如何与 Jest 一起工作?
- makefile - Makefile:为什么总是使用 `$(MAKE)` 而不是 `make`?
- ios - 我正在尝试安装“VLCKit”pod 文件