文章目录
初始化 React 项目的重要文件介绍:
public/index.html
项目的入口文件,引用了第三方类库啊,还可以引入 cdn ,或者样式,但是其中的 <div id="root"></div> 是项目的总容器,所有的内容存储在这个容器中。这个容器有且只能有一个。
src/index.tsx
document.getElementById(‘root’) 中的 "root" 便是 index.html 中的 "root" 了,便是引用页面内容了。在这里,也可以写一些内容(结构,样式,逻辑)。是整个项目的根组件。
src/App.tsx
项目主组件。
src/react-app-env.d.ts
引入 react 内部 ts 类型声明文件。
案例目录及介绍:
实现一个具有动态添加任务功能的界面
案例源码:
demo\src\components\TodoAdd.tsx
import React from 'react'
// 定义props类型
type Props = {
onAddTodo(text: string): void
}
// 定义state类型
type State = {
text: string
}
class TodoAdd extends React.Component<Props, State> {
// 初始化state
state: State = {
text: ''
}
// 动态修改text值
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({
text: e.target.value
})
}
// 按下回车触发添加函数
onAdd = (e: React.KeyboardEvent<HTMLInputElement>) => {
// 1.非空判断
const { text } = this.state;
// 去除空格后值依然为空 则退出
if (text.trim() === '') return
/*
// keyCode 属性即将废弃,因此在ts中会有删除线提示。
console.log(e.keyCode)
if (e.keyCode === 13) {
console.log('enter')
}
*/
// 使用code属性
if (e.code === 'Enter') {
// 2.向父元素传递数据触发添加函数
this.props.onAddTodo(this.state.text); // 子传父
// 3.清空文本框的值
this.setState({
text: ''
})
}
}
render() {
return (
<header className="header">
<input
className="new-todo"
placeholder="What needs to be done?"
autoFocus
value={this.state.text}
onChange={this.onChange}
onKeyDown={this.onAdd}
/>
</header>
)
}
}
// 暴露
export default TodoAdd
demo\src\components\TodoList.tsx
import React from 'react'
// 导入 TodoItem 类型
import { TodoItem } from '../todos'
// 提供 props 类型
interface Props {
list: TodoItem[]
}
// 类组件
class TodoList extends React.Component<Props> {
render() {
// console.log(this.props)
return (
<ul className="todo-list">
{/* 编辑样式:editing 已完成样式:completed */}
{this.props.list.map(todo => {
return (
<li key={todo.id} className={todo.done ? 'completed' : ''}>
<div className="view">
<input className="toggle" type="checkbox" />
<label>{todo.text}</label>
<button className="destroy" />
</div>
</li>
)
})}
</ul>
)
}
}
// 暴露
export default TodoList
demo\src\index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
demo\src\App.tsx
import { Component } from 'react'
// 导入组件
import TodoAdd from './components/TodoAdd';
import TodoList from './components/TodoList';
// 导入todos样式
import './App.css'
// 导入 TodoItem 类型
import { TodoItem } from './todos'
// 定义状态类型
type Todos = {
todos: TodoItem[]
}
// 定义状态初始数据
const todos: TodoItem[] = [
{
id: 1,
text: '吃饭',
done: true
},
{
id: 2,
text: '休息',
done: false
}
]
class App extends Component<{}, Todos> {
// 初始化state
state: Todos = {
todos
}
// 向todo列表添加元素
addTodo = (text: string) => {
// 解构获取todos列表
const { todos } = this.state;
// 动态增加id的值
const id = todos.length === 0 ? 1 : todos[todos.length - 1].id + 1;
// 修改todos列表
this.setState({
todos: [...this.state.todos, {
id,
text,
done: false
}]
})
}
render() {
return (
<section className="todoapp">
{/* 添加任务 */}
<TodoAdd onAddTodo={this.addTodo} />
{/* 列表组件 */}
<TodoList list={this.state.todos} />
</section>
)
}
}
export default App
demo\src\App.css
@import url('./css/todos-base.css');
@import url('./css/todos-index.css');
demo\src\todos.d.ts
// 类型声明文件:
// 任务项的类型
export type TodoItem = {
id: number
text: string
done: boolean
}
demo\src\react-app-env.d.ts
/// <reference types="react-scripts" />