Skip to content

脚手架

创建 React 项目

shell
# npx
npx create-react-app my-app
# npm
npm init react-app my-app
# yarn
yarn create react-app my-app

目录结构

text
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json #应用加壳(把网页变成Android/ios 软件)的配置文件
│   └── robots.txt #爬虫规则文件
└── src
    ├── App.css
    ├── App.js #根组件
    ├── App.test.js #用于给 App 组件做测试,一般不用
    ├── index.css
    ├── index.js #入口文件
    ├── logo.svg
    ├── serviceWorker.js #用于移动端开发, 支持离线浏览的功能
    └── setupTests.js #组件单元测试文件,需要 jest-dom 库支持

public/index.html 分析

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <!-- %PUBLIC_URL% 代表 public 文件夹的路径 -->
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <!-- 开启理想视口,用于做移动端网页的适配 -->
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <!-- 用于配置浏览器页签+地址栏的颜色(仅支持安卓手机浏览器) -->
    <meta name="theme-color" content="red" />
    <!-- 网站描述 -->
    <meta name="description" content="Web site created using create-react-app" />
    <!-- 用于指定网页添加到手机主屏幕后的图标 -->
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!-- 应用加壳时的配置文件 -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <!-- 若浏览器不支持 js 则展示标签中的内容 -->
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

样式的模块化

text
├── home
│   ├── index.css
│   └── index.js
└── table
    ├── index.css
    └── index.js

当两个组件内部标签元素有着共同的classname, 在根组件APP.js引入两个组件, 相同的classname会导致样式冲突, 且后引入的会覆盖之前的样式

解决办法

  • .css 文件改为 module.css
text
├── home
│   ├── index.module.css
│   └── index.js
└── table
    ├── index.module.css
    └── index.js
  • 在组件中导入样式
js
import { Component } from "react";
import home from "./index.module.css";

export default class Home extends Component {
  render() {
    return <h2 className={home.title}>Hello,React!</h2>;
  }
}

父子组件之间通信

  • 父传子使用 props
  • 子传父, 需要父组件给子组件传递一个箭头函数, 子组件调用该函数实现

父组件:

jsx
// 父组件
class Father extends Component {
  state: {
    todos: [{ id: "001", name: "吃饭", done: true }],
  };

  addTodo = (todo) => {
    const { todos } = this.state;
    const newTodos = [todo, ...todos];
    this.setState({ todos: newTodos });
  };

  render() {
    // 这里将addTodo方法传递给子组件调用
    return <List todos={this.state.todos} addTodo={this.addTodo} />;
  }
}

子组件:

jsx
class Son extends Component {
  // 由于 addTodo 是箭头函数,this 指向父组件实例对象,因此子组件调用它相当于父组件实例在调用
  handleClick = () => {
    this.props.addTodo({ id: "002", name: "敲代码", done: false });
  };

  render() {
    return <button onClick={this.handleClick}>添加</button>;
  }
}