Introduction
Learning purpose
When we learn GUI development, we generally think about two questions:
- How to design UI?
- 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
camelCase
camelCase (camelCase) to define attribute names instead of using the naming convention of HTML attribute names.For example, in JSX
class
becomesclassName
, andtabindex
becomestabIndex
.
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 HTMLAnd
<Welcome />
represents a component and needs to be used within the scopeWelcome
.
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;