首页 > 解决方案 > 在 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;

标签: javascriptarraysreactjsreact-native

解决方案


首先在父组件中创建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;


推荐阅读