[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