[TOC]
[组件 & Props](https://react.docschina.org/docs/components-and-props.html)
## :-: 自定义组件
:-: **特别注意:组件的名称首字母必须大写**
* 1.函数组件
* 通过函数返回一个元素
使用jsx语法(推荐):`function MyFuncComp(){ return <h1>jsx</h1> }`
通过React.createElement方法构建:`function MyFuncComp() { return React.createElement('h1', { style: { color: 'red' } }, 'createElement'); }`
* 2.类组件(功能更强大)
* 必须继承React.Components
* 必须提供rander函数,用于渲染
```
import React, { Component } from 'react';
export default class classComp extends Component {
// ···
render() { return ( <h1>Demo</h1> ) }
}
```
## :-: React - 无状态组件
```
// 函数组件
function component() { return <div>我是一个函数组件</div>; }
ReactDOM.render(component(), document.getElementById("root"));
// 标签组件(首字母必须大写)
function App() { return <div>我是一个标签组件</div>; }
ReactDOM.render(<App />, document.getElementById("root"));
```
## :-: 组件传参(props)
### 注意:
* 组件的属性应当使用小驼峰命名法。
* 数据传递为单向数据流。
* 组件无法改变自身的属性(props)(数据属于谁,谁才用权利改动它)
```
ReactDOM.render(<TagList data={"传参"} />, document.getElementById("root"));
--------------------------------------------------------------
import React from "react";
function TagList(props) {
console.log(props); // { data:'传参' }
return <div>我是一个组件 --{props.data}</div>;
}
export default TagList;
```
## :-: 组件状态(state)
### 注意事项
* 组件可以自行维护的数据
* 组件状态仅在类组件中有效
* 状态(state),本质上是类组件的一个属性,是对象类型
* 需要初始化,有两种方式
* 不能直接改变状态,因为React无法监控到状态发生了改变。
* 所以需要通过this.setState({})方法,使改变状态后的值重新渲染视图、
* 一但调用了this.setState(),会导致组件重新渲染、
### 组件的数据分两种
1. 参数(props) -- 该数据是其他组件传递的,所有权不属于组件自身,因此组件无法改变数据(只读)
2. 状态(state) -- 该组件是由自身创建的,所有权属于组件自身,组件有权限改变数据。(其他任何组件都无法改变)
```
ReactDOM.render(<TestComp timer={60} />, $root);
--------------------------------------------------------------
import React, { Component } from 'react';
// 组件状态(state)
export default class TestComp extends Component {
// 实际上React会自动加constructor构造函数,super(props)
constructor(props) {
super(props);
// 第一种初始化状态的方式(状态是必须要初始化的)
this.state = {
left: this.props.timer
}
this.time = setInterval(() => {
// 重新渲染 (一定要调用this.setState方法来改变原数据,不能直接修改数据,不然React监控不到变化)
this.setState({
// 数据混合 (React会将前后数据对比覆盖原有的数据并渲染到试图)
left: (this.state.left - 1)
});
if (this.state.left <= 0) clearInterval(this.time);
}, 100);
}
// 第二种初始化状态的方式(还在测试阶段,没有正式纳入js标准)
state = { left: this.props.timer } // 初始化状态 JS Next语法
render() {
return ( <h1>倒计时剩余:{this.state.left}</h1> )
}
}
```
## :-: React - 类组件
```
import React from "react";
// extends React.Component -- 继承React的生命周期
class TodoList extends React.Component {
// handleClick = this.handleClick.bind(this);
// 状态
// constructor() {
// super();
// this.state = {
// list: [1, 2, 3]
// };
// }
// 上面的this.state === 下面的state、
// 状态
state = {
inpVal: "123",
list: [1, 2, 3, 4, 5],
count: 0
};
// 必须要有 render 方法
render(h) {
return (
<>
{/* this === TodoList */}
<div>
{/* onChange={this.handleChange.bind(this)} */}
<input
type="text"
value={this.state.inpVal}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>添加</button>
</div>
<div>
<ul>
{this.state.list.map((item, index) => {
return (
<li key={index}>
{item}
<button
onClick={() => {
this.handleDelete(index);
}}
>
移除
</button>
</li>
);
})}
</ul>
</div>
<div>
<span>{this.state.count}</span>
<button onClick={this.handleAdd}>Add</button>
</div>
</>
);
}
handleChange = e => {
this.setState({ inpVal: e.target.value });
};
handleClick = () => {
this.setState({
list: [...this.state.list, this.state.inpVal],
inpVal: ""
});
};
handleDelete = index => {
const list = this.state.list;
list.splice(index, 1);
this.setState(list);
};
handleAdd = () => {
// 不能这样写,React会做批量更新处理。将相同的操作合并成一个、所以结果为3
// this.setState({ count: this.state.count + 1 });
// this.setState({ count: this.state.count + 2 });
// this.setState({ count: this.state.count + 3 });
// 正确的做法是
this.setState(prevState => {
return { count: prevState.count + 1 };
});
this.setState(prevState => {
return { count: prevState.count + 2 };
});
this.setState(prevState => {
return { count: prevState.count + 3 };
});
};
}
export default TodoList;
```
## :-: 受控组件 与 非受控组件
```
import React from "react";
class Control extends React.Component {
state = {
list: []
};
render() {
return (
<>
{/* 非受控组件 */}
<div>
taskA:
<input
type="text"
ref={dom => {
this.taskA = dom;
}}
/>
<button name="taskA" onClick={this.handleClick}>
添加A任务
</button>
</div>
<div>
taskB:
<input
type="text"
ref={dom => {
this.taskB = dom;
}}
/>
<button name="taskB" onClick={this.handleClick}>
添加B任务
</button>
</div>
<div>
<ul>
{this.state.list.map((item, index) => (
<li key={index + item}>{item}</li>
))}
</ul>
</div>
</>
);
}
handleClick = e => {
const type = e.target.name;
let task = this[type].value;
this[type].value = "";
if (type === "taskA") {
task = `任务A:${task}`;
} else if (type === "taskB") {
task = `任务B:${task}`;
}
this.setState({
list: [...this.state.list, task]
});
};
}
export default Control;
```
- 前端工具库
- HTML
- CSS
- 实用样式
- JavaScript
- 模拟运动
- 深入数组扩展
- JavaScript_补充
- jQuery
- 自定义插件
- 网络 · 后端请求
- css3.0 - 2019-2-28
- 选择器
- 边界样式
- text 字体系列
- 盒子模型
- 动图效果
- 其他
- less - 用法
- scss - 用法 2019-9-26
- HTML5 - 2019-3-21
- canvas - 画布
- SVG - 矢量图
- 多媒体类
- H5 - 其他
- webpack - 自动化构建
- webpack - 起步
- webpack -- 环境配置
- gulp
- ES6 - 2019-4-21
- HTML5补充 - 2019-6-30
- 微信小程序 2019-7-8
- 全局配置
- 页面配置
- 组件生命周期
- 自定义组件 - 2019-7-14
- Git 基本操作 - 2019-7-16
- vue框架 - 2019-7-17
- 基本使用 - 2019-7-18
- 自定义功能 - 2019-7-20
- 自定义组件 - 2019-7-22
- 脚手架的使用 - 2019-7-25
- vue - 终端常用命令
- Vue Router - 路由 (基础)
- Vue Router - 路由 (高级)
- 路由插件配置 - 2019-7-29
- 路由 - 一个实例
- VUEX_数据仓库 - 2019-8-2
- Vue CLI 项目配置 - 2019-8-5
- 单元测试 - 2019-8-6
- 挂载全局组件 - 2019-11-14
- React框架
- React基本使用
- React - 组件化 2019-8-25
- React - 组件间交互 2019-8-26
- React - setState 2019-11-19
- React - slot 2019-11-19
- React - 生命周期 2019-8-26
- props属性校验 2019-11-26
- React - 路由 2019-8-28
- React - ref 2019-11-26
- React - Context 2019-11-27
- PureComponent - 性能优化 2019-11-27
- Render Props VS HOC 2019-11-27
- Portals - 插槽 2019-11-28
- React - Event 2019-11-29
- React - 渲染原理 2019-11-29
- Node.js
- 模块收纳
- dome
- nodejs - tsconfig.json
- TypeScript - 2020-3-5
- TypeScript - 基础 2020-3-6
- TypeScript - 进阶 2020-3-9
- Ordinary小助手
- uni-app
- 高德地图api
- mysql
- EVENTS
- 笔记
- 关于小程序工具方法封装
- Tool/basics
- Tool/web
- parsedUrl
- request