React basic learning additional todo implementation code

Introduction

Learning purpose

When we learn GUI development, we generally think about two questions:

  1. How to design UI?
  2. How to realize front-end and back-end data interaction?

Question one

React introduces tsx syntax, which allows us to freely embed html in ts, allowing us to only write tsx code to control the UI, instead of putting all UI into one html file, making each part better maintain

In react, we use components to represent small parts

The question that comes with it is, how does react turn tsx code into a web page?

You know, we can use react to achieve web page effects without writing any html.

The answer is to use virtual dom, that is, dom managed by react. Our tsx syntax will be mapped to this virtual dom first, and then react will compare the changed parts, and then render to the dom in the browser. This can also reduce the need for Changes to browser DOM, saving performance

Question 2

Our data is modified through hooks , and different modifications can be encapsulated according to different needs.


React (React.js or ReactJS) is a JavaScript library developed and maintained by Facebook for building user interfaces. React is mainly used to build user interfaces in single page applications (Single Page Applications). Through component development, complex front-end applications can be built and maintained more easily.

The design goal of React is to improve the efficiency and maintainability of front-end development, making it easier for developers to build modern, responsive user interfaces. It is widely used in various web application development projects, and combined with other technologies (such as React Native), allows developers to build applications on different platforms such as web and mobile terminals in a similar way.

Operating environment

1. Create a React application

Open the terminal in the working directory, enter the following command, set the name to my-app and then all yes

npx create-next-app@latest

2. Go to the folder created by create-react-app and install typescript

cd my-app

3. Start React

npm run dev

Then the webpage will be automatically opened in the browser localhost:3000, and then you can see the official example.

HOOK

The format is as follows, explanation: Use setTodos to set todos, and the initial value is the empty list of <Todo[]>([])

  const [todos, setTodos] = useState<Todo[]>([])

Then we can use this to manage todos, as follows

  const addTodo = (text: string) => {
    const newTodo = {
      id: Date.now(),
      text,
      completed: false
    }
    setTodos([...todos, newTodo])//打开旧的,添加新的
  }
  
  const deleteTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id))
    //将不需要删除的筛选出来称为新的
  }

  const toggleTodo = (id: number) => {
    setTodos(todos.map(todo => {
      if (todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo
    }))
  }

TSX

TSX is a syntax extension for nested XML tags in TypeScript code. Conveniently describes the structure of the user interface.

Therefore, it is used in the same way as other ts types, and can be understood by analogy with strings .

Common usage

statement

const element = <h1>Hello, world!</h1>;

format

const name = "Josh Perez";
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(element, document.getElementById("root"));

return value

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

Attributes

You can specify property values ​​as string literals by using quotes:

const element = <div tabIndex="0"></div>;

You can also use curly braces to insert a JavaScript expression into the property value:

const element = <img src={user.avatarUrl}></img>;

Habit

When embedding JavaScript expressions in properties, do not put quotes around the curly braces. You should use only one of quotes (for string values) or braces (for expressions), not both for the same property.

Because JSX is syntactically closer to JavaScript than to HTML, React DOM uses camelCasecamelCase (camelCase) to define attribute names instead of using the naming convention of HTML attribute names.

For example, in JSX classbecomes className, and tabindexbecomes tabIndex.

principle

Babel will translate JSX into a React.createElement()function call called.

The following two sample codes are completely equivalent:

const element = <h1 className="greeting">Hello, world!</h1>;
const element = React.createElement(
  "h1",
  { className: "greeting" },
  "Hello, world!"
);

React.createElement()does some checks beforehand to help you write error-free code, but in reality it creates an object like this:

const element = {
  type: "h1",
  props: {
    className: "greeting",
    children: "Hello, world!",
  },
};

These objects are called "React elements". They describe what you want to see on the screen. React reads these objects and uses them to build the DOM and keep it updated.

render

Render new elements

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById("root"));

update element

React elements are immutable objects. The only way to update the UI is to create a completely new element and pass it in ReactDOM.render().

Consider a timer example:

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById("root"));
}

setInterval(tick, 1000);

This example will setInterval()call the callback function every second ReactDOM.render(). That is, it renders a new React element every second and passes it in ReactDOM.render().

components

components

It is actually a function, and props accepts any input parameters. However, the general parameters are still written for us to call.

When using it, we can use it like normal html, but the parameters must be passed

function Welcome(props) {
    
    
  return <h1>Hello, {
    
    props.name}</h1>;
}

Use it like html, as follows

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(element, document.getElementById("root"));

Note: Component names must start with a capital letter .

React treats components starting with a lowercase letter as native DOM tags. For example, <div />the div tag representing HTML

And <Welcome />represents a component and needs to be used within the scope Welcome.

use

The types of parameters received as follows can be explained through the interface AddTodoProps, and then the specific usage is explained.

AddTodo.tsx

import { useState } from "react";

interface AddTodoProps {
    addTodo: (text: string) => void
}

function AddTodo({ addTodo }: AddTodoProps) {
    const [text, setText] = useState('')

    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        if (text.trim().length === 0) {
            return
        }
        addTodo(text)
        setText('')
    }
    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                value={text}
                onChange={e => setText(e.target.value)}
            />
            <button>Add</button>
        </form>
    )
}

export default AddTodo;

page.tsx

Use it like a normal html tag, pay attention to passing parameters

<AddTodo addTodo={addTodo}></AddTodo>

todo all codes

pages.tsx

"use client"
import AddTodo from "./components/AddTodo"
import TodoList from "./components/TodoList"
import TodoFilter from "./components/TodoFilter"
import { useState } from "react"
import { Todo } from "./types"

export default function Home() {
  const [todos, setTodos] = useState<Todo[]>([])//在光标处按ctrl可以查看函数原型
  const [filter, setFilter] = useState('all')
  const addTodo = (text: string) => {
    const newTodo = {
      id: Date.now(),
      text,
      completed: false
    }
    setTodos([...todos, newTodo])//打开旧的,添加新的
  }

  const deleteTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id))
    //将不需要删除的筛选出来称为新的
  }

  const toggleTodo = (id: number) => {
    setTodos(todos.map(todo => {
      if (todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo
    }))
  }

  const getFilteredTodos = () => {
    switch (filter) {
      case 'active':
        return todos.filter(todo => !todo.completed)
      case 'completed':
        return todos.filter(todo => todo.completed)
      default:
        return todos;
    }
  }


  return (
    <div>
      <h1>Todo List</h1>
      <AddTodo addTodo={addTodo}></AddTodo>
      <TodoList todos={getFilteredTodos()} deleteTodo={deleteTodo} toggleTodo={toggleTodo} />
      <TodoFilter setFilter={setFilter} ></TodoFilter>
    </div>
  )
}

types.ts

export interface Todo {
    
    
    id: number;
    text: string;
    completed: boolean;
}

components

AddTodo.tsx

import { useState } from "react";

interface AddTodoProps {
    addTodo: (text: string) => void
}

function AddTodo({ addTodo }: AddTodoProps) {
    const [text, setText] = useState('')

    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        if (text.trim().length === 0) {
            return
        }
        addTodo(text)
        setText('')
    }
    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                value={text}
                onChange={e => setText(e.target.value)}
            />
            <button>Add</button>
        </form>
    )
}

export default AddTodo;

TodoFilter.tsx

function TodoFilter({ setFilter }: any) {
    return (
        <div>
            <button onClick={() => setFilter('all')}>All</button>
            <button onClick={() => setFilter('active')}>Active</button>
            <button onClick={() => setFilter('completed')}>Completed</button>
        </div>
    )
}

export default TodoFilter;

TodoItem.tsx

interface TodoListProps {
    todo: any;
    toggleTodo: (id: number) => void;
    deleteTodo: (id: number) => void;
}


function TodoItem({ todo, toggleTodo, deleteTodo }: TodoListProps) {
    return (
        <li style={
   
   { textDecoration: todo.completed ? 'line-through' : 'none' }}>
            {todo.text}
            <button onClick={() => toggleTodo(todo.id)}>切换</button>
            <button onClick={() => deleteTodo(todo.id)}>删除</button>
        </li>
    )
}
export default TodoItem;

TodoList.tsx

import { Todo } from "../types";
import TodoItem from "./TodoItem";

interface TodoListProps {
    todos: Array<Todo>;
    toggleTodo: (id: number) => void;
    deleteTodo: (id: number) => void;
}

function TodoList({ todos, toggleTodo, deleteTodo }: TodoListProps) {
    return (
        <ul>
            {todos.map(todo => (
                <TodoItem key={todo.id} todo={todo} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />
            ))}
        </ul>
    )
}

export default TodoList;

Guess you like

Origin blog.csdn.net/killsime/article/details/135310284