创建一个带有反应和样式组件的托多列表应用程序
#javascript #初学者 #reactnative #android

todo列表是一个简单但有用的应用程序,可帮助您跟踪任务和目标。它允许您添加,编辑,删除和标记项目。在本文中,我们将学习如何使用React Antial创建一个TODO List应用程序,这是一个流行的框架,用于使用JavaScript构建跨平台移动应用程序。

React Native是一个框架,可让您使用React,一个用于构建用户界面的库来为iOS和Android创建本机应用程序。 React Native使用本机组件代替Web组件,这意味着您可以访问本机平台的功能和性能。 React Native还支持热重载和实时重新加载,这意味着您可以立即看到应用程序中的更改而无需重建。

要使用React Native创建一个TODO列表应用程序,我们将按照以下步骤进行操作:

  1. 设置开发环境并安装依赖项。

  2. 创建将渲染待办事项列表和输入字段的主要应用程序组件。

  3. 创建一个自定义任务组件,该组件将显示每个待办事项并处理编辑和删除操作。

  4. 使用USESTATE钩管理应用程序的状态,例如任务列表和当前输入值。

  5. 使用AsyncStorage中的使用效果挂钩从本地存储中保存和加载任务。

  6. 添加一些样式和图标以使应用看起来更好。

让我们看看如何详细实施每个步骤。

步骤1:设置开发环境并安装依赖项

要开始构建我们的应用程序,我们需要设置我们的开发环境并安装一些依赖性。我们将使用Expo,该工具简化了开发和测试React Antive Apps的过程。博览会提供了一组工具和服务,可让您在设备或模拟器上运行应用程序而无需安装任何本机依赖关系。

要安装博览会,我们需要在系统上安装node.js和npm。您可以从here下载它们。然后,我们可以在终端中运行以下命令:

npm install --global expo-cli

这将在我们的系统上全球安装Expo命令线接口(CLI)。

接下来,我们需要使用博览会创建一个新项目。我们可以通过运行来做到这一点:

expo init TodoList

这将创建一个带有一些样板代码和配置文件的名为Todolist的新文件夹。我们可以从博览会提供的选项中为我们的项目选择一个模板。对于本教程,我们将使用空白模板,这为我们提供了最小的设置。

然后,我们需要导航到我们的项目文件夹并通过运行:

启动开发服务器

cd TodoList

expo start

这将打开带有QR码的网页和一些运行我们应用程序的选项。我们可以使用Expo GO应用程序使用设备扫描QR码,我们可以从here下载iOS或here for Android。另外,我们可以通过单击iOS模拟器上的运行或在Android设备/模拟器按钮上运行来使用计算机上的模拟器或模拟器。

在开始编码之前,我们需要为应用程序安装一些其他依赖项。我们将使用样式的组件,一个库,使我们可以在JavaScript中编写CSS来样式组件。我们还将使用React-Native-Vector-Icons,这是一个为我们提供应用程序图标的库。要安装这些依赖项,我们需要运行:

npm install styled-components react-native-vector-icons

我们还需要通过运行:

将React-Native-vector-Icons库链接到我们的项目

expo install @expo/vector-icons

这将确保图标可用于我们的应用。

步骤2:创建将呈现待办事项列表和输入字段的主要应用程序组件

现在,我们已经设置了项目并安装了依赖项,我们可以开始编码我们的应用程序。我们将使用Visual Studio代码作为我们的代码编辑器,但是您可以使用您选择的任何编辑器。

我们将首先创建将呈现TODO列表和输入字段的主要应用程序组件。为此,我们需要在我们的项目文件夹中打开app.js文件,并用以下代码替换其内容:


// Import React and useState hook

import React, { useState, useEffect } from "react";

import { StatusBar } from "react-native";
// Import styled-components

import styled from "styled-components/native";

// Import Task component

import Task from "./src/Task";

import AsyncStorage from "@react-native-async-storage/async-storage";
// Create a container component using styled-components

const Container = styled.View`
  flex: 1;

  background-color: #e8eaed;
`;

// Create an input component using styled-components

const Input = styled.TextInput`
  padding: 15px;

  padding-left: 55px;

  border-color: #c0c0c0;

  border-width: 1px;

  border-radius: 60px;

  width: 90%;

  margin: 20px;
`;

// Create an icon component using styled-components

const Icon = styled.Image`
  width: 30px;

  height: 30px;

  position: absolute;

  top: 35px;

  left: 30px;
`;

// Create a list component using styled-components

const List = styled.ScrollView`
  margin: 20px;
`;

// Create the main App component

export default function App() {
  // Define the state for the input value

  const [input, setInput] = useState("");

  // Define the state for the list of tasks

  const [tasks, setTasks] = useState([]);

  // Define a function to handle the input change

  const handleChange = (value) => {
    setInput(value);
  };

  // Define a function to handle the submit action

  const handleSubmit = () => {
    // Check if the input is not empty

    if (input.length > 0) {
      // Create a new task object

      const newTask = {
        id: Math.random().toString(),

        title: input,

        done: false,
      };

      // Update the list of tasks

      setTasks([newTask, ...tasks]);

      // Reset the input value

      setInput("");
    }
  };

  useEffect(() => {
    // Save tasks to local storage

    AsyncStorage.setItem("tasks", JSON.stringify(tasks));
  }, [tasks]);

  useEffect(() => {
    // Load tasks from local storage

    AsyncStorage.getItem("tasks").then((value) => {
      // Check if value is not null

      if (value) {
        // Parse value into an array and update tasks state variable

        setTasks(JSON.parse(value));
      }
    });
  }, []);

  return (
    // Render the container component

    <Container>
      <StatusBar
        animated={true}
        backgroundColor="#c0c0c0"
        barStyle={"dark-content"}
        showHideTransition={"fade"}
      />
      <Input
        value={input}
        onChangeText={handleChange}
        placeholder="Enter a task"
        onSubmitEditing={handleSubmit}
      />
      <Icon source={require("./assets/favicon.png")} />
      <List>
        {tasks.map((task) => (
          <Task key={task.id} task={task} />
        ))}
      </List>
    </Container>
  );
}


让我们分解此代码的作用:

  • 首先,我们导入“反应”和“反应”的usestate钩子。 USESTATE挂钩使我们能够管理组件的状态,即随时间变化的数据。我们将使用它来存储输入值和任务列表。

  • 接下来,我们从“样式组件/本机”中导入样式。这使我们可以使用CSS语法创建自定义组件。我们将使用它来对我们的容器,输入,图标和列表组件进行样式。

  • 然后,我们从“ ./components/task”导入任务。这是一个自定义组件,我们将在以后创建以显示每个待办事项。我们将把任务对象作为prop。

  • 传递给
  • 之后,我们使用stypled.view创建一个容器组件。这是一个基本组件,它呈现一个可以包含其他组件的视图。我们给它一个Flex:1属性,这意味着它将占用其父母中的所有可用空间。我们还给它一个背景色:#e8eaed属性,将其背景颜色设置为浅灰色。

  • 接下来,我们使用stypled.textinput创建一个输入组件。这是一个组件,可渲染可以接受用户输入的输入字段。我们给它一些填充,边框,边界 - 拉迪乌斯,宽度和边缘属性,以使其看起来不错。我们还给它一个左衬里:55px属性,它为图标组件创建了一些空间,我们将稍后添加。

  • 然后,我们使用stypled.image创建图标组件。这是从源文件呈现图像的组件。我们给它一些宽度,高度,位置,顶部和左侧属性,以将其定位在输入组件的顶部。我们将使用此图标作为添加新任务的按钮。

  • 接下来,我们使用stypled.scrollview创建一个列表组件。这是一个呈现可滚动视图的组件,可以包含其他组件。我们给它一些边缘以创建周围的空间。

  • 之后,我们创建主应用程序组件并将其导出为默认值。这是我们应用程序的根组件,它将呈现所有其他组件。

  • 在应用程序组件中,我们使用USESTATE挂钩:输入和任务定义了两个状态变量。输入变量保存输入字段的当前值,任务变量包含任务对象的数组。每个任务对象都有一个ID,标题和完成的属性。 ID是每个任务的唯一标识符,标题是任务的文本,完成的是一个布尔值,它指示任务是否已完成。我们还为每个状态变量定义了两个设置器函数:setInput和settasks。这些功能使我们能够使用新值更新状态变量。

  • 接下来,我们定义两个函数来处理输入更改并提交操作:处理和handlesubmit。 HandleChange函数将值作为参数作为参数,并使用该值更新输入状态变量。 HandleSubmit函数检查输入值是否不是空的,并以该值作为标题创建一个新的任务对象。它还为新任务生成随机ID,并将其完成的属性设置为False。然后,它通过

  • 更新任务状态变量

步骤3:创建一个自定义任务组件,该组件将显示每个待办事项并处理编辑和删除操作

在此步骤中,我们将创建一个自定义任务组件,该组件将渲染我们列表中的每个待办事项。我们还将添加一些功能以编辑,删除和标记任务。为此,我们需要在组件文件夹中创建一个名为task.js的新文件,并添加以下代码:


// Import React and useState hook

import React, { useState } from "react";

// Import styled-components

import styled from "styled-components/native";

// Import icons from react-native-vector-icons

import { AntDesign, Feather } from "@expo/vector-icons";

// Create a container component using styled-components

const Container = styled.View`
  flex-direction: row;

  align-items: center;

  background-color: #fff;

  padding: 15px;

  margin-bottom: 20px;

  border-radius: 10px;
`;

// Create a text component using styled-components

const Text = styled.Text`
  font-size: 18px;

  margin-left: 15px;

  flex: 1;
`;

// Create an input component using styled-components

const Input = styled.TextInput`
  font-size: 18px;

  margin-left: 15px;

  flex: 1;
`;

// Create an icon container component using styled-components

const IconContainer = styled.TouchableOpacity`
  width: 30px;

  height: 30px;

  align-items: center;

  justify-content: center;
`;

// Create the Task component and export it as default

export default function Task({ task }) {
  // Define the state for the editing mode

  const [editing, setEditing] = useState(false);

  // Define the state for the edited title

  const [title, setTitle] = useState(task.title);

  // Define a function to handle the edit action

  const handleEdit = () => {
    // Toggle the editing mode

    setEditing(!editing);

    // Update the title with the edited value

    setTitle(title);

    // TODO: Save the edited task to the local storage
  };

  // Define a function to handle the input change

  const handleChange = (value) => {
    // Update the title state variable with the input value

    setTitle(value);
  };

  // Define a function to handle the delete action

  const handleDelete = () => {
    // TODO: Delete the task from the local storage and update the tasks state variable in the App component

    alert("Delete " + task.title);
  };

  // Define a function to handle the done action

  const handleDone = () => {
    // TODO: Toggle the done property of the task in the local storage and update the tasks state variable in the App component

    alert("Done " + task.title);
  };

  return (
    // Render the container component and pass the task id as a key prop

    <Container key={task.id}>
      <IconContainer onPress={handleDone}>
        <AntDesign
          name={task.done ? "checkcircle" : "checkcircleo"}
          size={24}
          color="#55BCF6"
        />
      </IconContainer>
      {editing ? (
        <Input value={title} onChangeText={handleChange} />
      ) : (
        <Text
          style={{ textDecorationLine: task.done ? "line-through" : "none" }}
        >
          {title}
        </Text>
      )}

      <IconContainer onPress={handleEdit}>
        <Feather name={editing ? "check" : "edit"} size={24} color="#55BCF6" />
      </IconContainer>

      <IconContainer onPress={handleDelete}>
        <AntDesign name="delete" size={24} color="#55BCF6" />
      </IconContainer>
    </Container>
  );
}


让我们分解此代码的作用:

  • 首先,我们导入“反应”和“反应”的usestate钩子。 USESTATE挂钩使我们能够管理组件的状态。我们将使用它来存储编辑模式和每个任务的编辑标题。

  • 接下来,我们从“样式组件/本机”中导入样式。这使我们可以使用CSS语法创建自定义组件。我们将使用它来对我们的容器,文本,输入和图标容器组件进行样式。

  • 然后,我们从“@expo/vector-icons”中导入反设计和羽毛。这是我们可以在应用程序中使用的两组图标。我们将使用它们为每个任务渲染检查,编辑和删除图标。

  • 之后,我们使用stypled.view创建一个容器组件。这是一个基本组件,它呈现一个可以包含其他组件的视图。我们给它一个弹性方向:行属性,这意味着它将水平安排孩子。我们还给它一个对齐项目:中心财产,这意味着它将在中心垂直对齐。我们还给它一些背景色,填充,边缘底和边界 - 拉迪乌斯属性,以使其看起来不错。

  • 接下来,我们使用stypled.text创建一个文本组件。这是呈现一些文本的组件。我们给它一个字体大小:18px属性,将其字体大小设置为18像素。我们还给它一个左键:15px属性,该属性在左侧创造了一些空间。我们还给它一个flex:1属性,这意味着它将占用其父母的所有剩余空间。

  • 然后,我们使用stypled.textinput创建一个输入组件。这是一个组件,可渲染可以接受用户输入的输入字段。我们给它与文本组件相同的属性,除了保证金左派属性。

  • 接下来,我们使用stypouchable.touchable创建一个图标容器组件。这是一个可以响应触摸事件的视图的组件。我们给它一些宽度,高度,对准项目和合理性特性,以将其定位为中央带有图标的正方形。

  • 之后,我们创建任务组件并将其导出为默认值。这是我们将使用的自定义组件在列表中显示每个待办事项。我们将其传递给“任务对象”作为来自应用程序组件的道具。

  • 在任务组件中,我们使用USESTATE HONK:编辑和标题定义了两个状态变量。编辑变量具有一个布尔值,该值指示该任务是否处于编辑模式。标题变量具有任务标题的当前值。我们还为每个状态变量定义了两个设置器函数:设置和设置。这些功能使我们能够使用新值更新状态变量。

  • 接下来,我们定义四个功能来处理编辑,删除,完成和输入更改操作:handledit,andledelete,andledone和Handlechange。 handleedit函数可切换编辑模式,并使用编辑值更新标题。 WandledElete函数从本地存储中删除任务,并在应用程序组件中更新任务状态变量。 HandledOne函数在本地存储中切换任务的完成属性,并在应用程序组件中更新任务状态变量。手理学功能更新标题状态变量,带有输入值。

  • 最后,我们返回一些JSX代码,这些JSX代码具有一些图标容器组件以及根据编辑模式的文本或输入组件。

这就是我们创建一个自定义任务组件的方式,该组件将显示每个待办事项并处理编辑和删除操作。

步骤4:使用USESTATE钩管理应用程序的状态,例如任务列表和当前输入值

在此步骤中,我们将学习如何使用Usestate钩子来管理应用程序的状态。状态是在我们应用程序中随时间变化的数据,例如任务列表和当前输入值。 USESTATE挂钩是一个函数,使我们可以在功能组件中创建和更新状态变量。

要使用usestate钩子,我们需要从文件顶部的“ react”导入它:


import React, { useState } from "react";

然后,我们需要将其称为组件中,并将其传递给状态变量的初始值。 USESTATE钩返回一个带有两个元素的数组:状态变量和设置器函数。我们可以使用破坏性的数组将它们分配给某些名称,例如:


const [state, setState] = useState(initialValue);

状态变量保留我们状态的当前值,SetState函数允许我们使用新值更新它。只要它们有意义且一致,我们就可以使用所需的任何名称。

例如,在我们的应用程序组件中,我们有两个状态变量:输入和任务。输入变量保存输入字段的当前值,任务变量包含任务对象的数组。我们分别用一个空字符串和一个空数组来初始化它们:


const [input, setInput] = useState("");

const [tasks, setTasks] = useState([]);

我们可以在组件中使用这些状态变量来渲染输入字段和任务列表。例如,我们可以将输入值作为支架传递给输入组件:


<Input value={input} />

我们还可以映射任务数组并为每个项目渲染一个任务组件:


{tasks.map((task) => (

<Task key={task.id} task={task} />

))}

要更新状态变量,我们需要调用具有新值的设置器函数。例如,在我们的处理函数中,我们更新输入状态变量,并从输入组件的OnChangeText Prop中获得的值:


const handleChange = (value) => {

setInput(value);

};

同样,在我们的handlesubmit函数中,我们通过创建以输入值作为标题的新任务对象来更新任务状态变量,并将其添加到任务阵列的开头:


const handleSubmit = () => {

if (input.length > 0) {

const newTask = {

id: Math.random().toString(),

title: input,

done: false,

};

setTasks([newTask, ...tasks]);

setInput("");

}

};

我们还可以将这些设置器函数作为道具传递给需要更新状态的其他组件。例如,我们可以将Settasks功能作为支撑传递给任务组件,以便它可以删除或标记任务:


<Task key={task.id} task={task} setTasks={setTasks} />

这就是我们使用USESTATE挂钩管理应用程序状态的方式。 USESTATE HONK允许我们在不使用类或生命周期方法的情况下创建和更新功能组件中的状态变量。它还可以确保我们的组件在我们的状态发生变化时重新呈现。

步骤5:使用usyncstorage从本地存储中保存和加载任务

在此步骤中,我们将学习如何使用Asyncstorage从本地存储中保存和加载任务。使用效果挂钩是一个函数,使我们能够在功能组件中执行副作用,例如获取数据,更新文档标题或将数据保存到本地存储中。异关系是一个模块,它为我们提供了一个简单且异步的API,可从设备的本地存储中存储和检索数据。

要使用使用效果钩,我们需要从文件顶部的“ react”导入它:


import React, { useState, useEffect } from "react";

然后,我们需要将其称为组件中,并将其传递给回调功能和可选的依赖项数组。回调函数是我们编写副作用代码的位置,而依赖关系数组是我们指定副作用所取决于的变量的位置。除非我们提供依赖项数组,否则使用效果挂钩将在每个组件的每一个渲染后都会运行回调函数。如果我们提供依赖关系数组,则使用效果挂钩只会在数组中的一个变量更改时运行回调函数。

例如,在我们的应用程序组件中,我们希望在更改时将任务状态变量保存到本地存储。为此,我们需要将使用效果挂钩带有一个回调函数,该函数调用Asyncstorage.setItem使用键和值调用。关键是一个标识我们数据的字符串,值是代表我们数据的字符串。我们可以使用JSON.Stringify将任务数组转换为字符串。我们还需要将[任务]作为依赖项数组传递,以便仅当任务更改时使用效果挂钩:


useEffect(() => {

// Save tasks to local storage

AsyncStorage.setItem("tasks", JSON.stringify(tasks));

}, [tasks]);

同样,当我们的组件首次安装时,我们希望从本地存储加载任务状态变量。为此,我们需要将另一个使用效果挂钩带有一个回调函数,该回调函数与键调用asyncstorage.getItem。密钥是我们用来保存数据的字符串。 AsyncStorage.GETITEM方法返回一个承诺,如果找不到数据,则可以以值或空解决。我们可以使用json.parse将值转换为数组,并使用它更新任务状态变量。我们还需要将空数组作为依赖项数组传递,以便使用效果钩仅运行一次:


useEffect(() => {

// Load tasks from local storage

AsyncStorage.getItem("tasks").then((value) => {

// Check if value is not null

if (value) {

// Parse value into an array and update tasks state variable

setTasks(JSON.parse(value));

}

});

}, []);

要使用asyncstorage,我们需要从“@react-native-async-storage/async-staregora”中导入它:


import AsyncStorage from "@react-native-async-storage/async-storage";

我们还需要通过运行以作为依赖项安装它:

npm install @react-native-async-storage/async-storage

这就是我们使用usyncstorage从本地存储中保存和加载任务的方式。使用效果挂钩使我们无需类别或生命周期方法就可以在功能组件中执行副作用。它还确保我们的副作用与我们的州和道具一致。异步使我们能够以异步方式从设备的本地存储中存储和检索数据。

步骤6:添加一些样式和图标以使应用看起来更好

在此步骤中,我们将学习如何添加一些样式和图标以使我们的应用看起来更好。我们将使用样式的组件,一个库,使我们可以在JavaScript中编写CSS来样式组件。我们还将使用React-Native-vector-Icons,这是一个为我们提供应用程序图标的库。

要使用样式组件,我们需要通过运行来将其作为依赖项安装:

npm install styled-components

然后,我们需要从文件顶部的“样式组件/本机”导入它:


import styled from "styled-components/native";

要使用React-native-vector-icons,我们需要通过运行来将其作为依赖项安装:

npm install react-native-vector-icons

然后,我们需要通过运行链接到我们的项目:

expo install @expo/vector-icons

然后,我们需要导入要从“@expo/vector-icons”中使用的图标:


import { AntDesign, Feather } from "@expo/vector-icons";

我们可以使用样式组件使用CSS语法创建自定义组件。例如,我们可以使用Stytled.view:
创建一个容器组件


const Container = styled.View`

flex: 1;

background-color: #e8eaed;

`;

我们还可以使用样式的组件来设计现有组件,例如文本输入或图像。例如,我们可以使用Stytled.textinput创建一个输入组件:


const Input = styled.TextInput`

padding: 15px;

padding-left: 55px;

border-color: #c0c0c0;

border-width: 1px;

border-radius: 60px;

width: 250px;

margin: 20px;

`;

我们可以使用React-Native-vector-icons从不同集合(例如Antdesign或Feather)呈现图标。例如,我们可以使用Antdesign组件从Antdesign渲染图标:


<AntDesign name="checkcircle" size={24} color="#55BCF6" />

我们还可以使用诸如名称,大小和颜色之类的道具来自定义图标。

让我们看看如何使用这些库来设计我们的应用程序。

造型应用程序组件

在应用程序组件中,我们将设计容器,输入,图标和列表组件。

容器组件是一个基本组件,它呈现一个可以包含其他组件的视图。我们将给它一个flex:1属性,这意味着它将占用其父母中的所有可用空间。我们还将给它一个背景色:#e8eaed属性,将其背景颜色设置为浅灰色。

输入组件是渲染可以接受用户输入的输入字段的组件。我们将给它一些填充,边框,边界 - 拉迪乌斯,宽度和边缘属性,以使其看起来不错。我们还将给它一个左侧左:55PX属性,该属性为图标组件创建了一些空间,我们将稍后添加。

图标组件是从源文件呈现图像的组件。我们将给它一些宽度,高度,位置,顶部和左侧属性,以将其定位在输入组件的顶部。我们将使用此图标作为添加新任务的按钮。

列表组件是一个呈现可滚动视图的组件,可以包含其他组件。我们将给它一些边缘以创建周围的空间。

这是带有样式的应用程序组件的代码:


// Import React and useState hook

import React, { useState } from "react";



// Import styled-components

import styled from "styled-components/native";



// Import Task component

import Task from "./components/Task";



// Create a container component using styled-components

const Container = styled.View`

flex: 1;

background-color: #e8eaed;

`;



// Create an input component using styled-components

const Input = styled.TextInput`

padding: 15px;

padding-left: 55px;

border-color: #c0c0c0;

border-width: 1px;

border-radius: 60px;

width: 250px;

margin: 20px;

`;



// Create an icon component using styled-components

const Icon = styled.Image`

width: 30px;

height: 30px;

position: absolute;

top: 35px;

left: 30px;

`;



// Create a list component using styled-components

const List = styled.ScrollView`

margin: 20px;

`;



// Create the main App component

export default function App() {

// Define the state for the input value

const [input, setInput] = useState("");



// Define the state for the list of tasks

const [tasks, setTasks] = useState([]);



// Define a function to handle the input change

const handleChange = (value) => {

setInput(value);

};



// Define a function to handle the submit action

const handleSubmit = () => {

// Check if the input is not empty

if (input.length > 0) {

// Create a new task object

const newTask = {

id: Math.random().toString(),

title: input,

done: false,

};



// Update the list of tasks

setTasks([newTask, ...tasks]);



// Reset the input value

setInput("");

}

};



return (

// Render the container component

<Container>

// Render the input component and pass the input value and change handler as props

<Input

value={input}

onChangeText={handleChange}

placeholder="Enter a task"

onSubmitEditing={handleSubmit}

/>

// Render the icon component and pass the source as a prop

<Icon source={require("./assets/add.png")} />

// Render the list component

<List>

// Map over the tasks array and render a Task component for each item

{tasks.map((task) => (

<Task key={task.id} task={task} />

))}

</List>

</Container>

);

}

造型任务组件

在任务组件中,我们将设计容器,文本,输入和图标容器组件。我们还将使用来自React-Native-vector-Icons的图标来渲染每个任务的检查,编辑和删除图标。

容器组件是一个基本组件,它呈现一个可以包含其他组件的视图。我们将给它一个弹性方向:行属性,这意味着它将水平安排孩子。我们还将给它一个Align-Intems:中心财产,这意味着它将在中心垂直对齐其子女。我们还将给它一些背景色,填充,边缘底部和边界 - 拉迪乌斯的属性,以使其看起来不错。

文本组件是呈现一些文本的组件。我们将给它一个字体大小:18px属性,将其字体大小设置为18像素。我们还将给它一个左键:15px属性,该属性在左侧创建一些空间。我们还将给它一个flex:1属性,这意味着它将占用其父母的所有剩余空间。

输入组件是渲染可以接受用户输入的输入字段的组件。除了边距 - 左属性外,我们将赋予它与文本组件相同的属性。

图标容器组件是一个可以响应触摸事件的视图的组件。我们将给它一些宽度,高度,对准项目和合理性特性,以将其定位为中央带有图标的正方形。

我们将使用Antdesign和Feather的图标来为每个任务渲染检查,编辑和删除图标。我们将使用诸如名称,大小和颜色之类的道具来自定义图标。

这是带有样式和图标的任务组件的代码:


// Import React and useState hook

import React, { useState } from "react";



// Import styled-components

import styled from "styled-components/native";



// Import icons from react-native-vector-icons

import { AntDesign, Feather } from "@expo/vector-icons";



// Create a container component using styled-components

const Container = styled.View`

flex-direction: row;

align-items: center;

background-color: #fff;

padding: 15px;

margin-bottom: 20px;

border-radius: 10px;

`;



// Create a text component using styled-components

const Text = styled.Text`

font-size: 18px;

margin-left: 15px;

flex: 1;

`;



// Create an input component using styled-components

const Input = styled.TextInput`

font-size: 18px;

margin-left: 15px;

flex: 1;

`;



// Create an icon container component using styled-components

const IconContainer = styled.TouchableOpacity`

width: 30px;

height: 30px;

align-items: center;

justify-content: center;

`;



// Create the Task component and export it as default

export default function Task({ task }) {

// Define the state for the editing mode

const [editing, setEditing] = useState(false);



// Define the state for the edited title

const [title, setTitle] = useState(task.title);



// Define a function to handle the edit action

const handleEdit = () => {

// Toggle the editing mode

setEditing(!editing);

// Update the title with the edited value

setTitle(title);

// TODO: Save the edited task to the local storage

};



// Define a function to handle the input change

const handleChange = (value) => {

// Update the title state variable

使用React Native的TODO列表应用程序的项目结构如下:

  • 该项目的根文件夹称为Todolist,其中包含Expo生成的一些配置文件和文件夹,例如App.json,Package.json,Node_modules等。

  • SRC文件夹包含我们应用程序的源代码,该代码由两个文件组成:app.js and task.js。 app.js是渲染应用程序组件的主文件,其中包含输入字段和任务列表。 task.js是定义任务组件的文件,该文件显示每个待办事项并处理编辑和删除操作。

  • 资产文件夹包含我们在应用中使用的映像文件,例如add.png,它是添加新任务的图标。

  • 组件文件夹包含我们使用样式组件(例如容器,输入,图标,列表,文本和IconContainer)创建的自定义组件。这些组件用于设计我们的应用程序并使其看起来更好。

这是一个显示项目结构的图:


TodoList
├── assets
│ └── favicon.png
├── src
│ └── Task.js
├── App.js
├── app.json
├── package.json
└── node_modules

I hope this helps you understand the project structure of our app. If you have any questions or feedback, please let me know in the comments below.

您非常欢迎!我很高兴您喜欢阅读我的文章,并学到了一些新的文章。感谢您的反馈和支持。感谢您成为我博客的忠实读者。 ð

如果您想阅读更多我的文章,可以关注我。您也可以在TwitterInstagram上关注我,以获取有关我工作的最新更新。我希望很快能在见到你! ð