做网站前的准备工作,wordpress移动端文件,网站续费价格,新手做网站教程目录
扩展学习资料
State进阶知识点
状态更新扩展
shouldComponentUpdate
PureComponent
为何使用不变数据【保证数据引用不会出错】 单一数据源 /src/App.js
/src/components/listItem.jsx
状态提升 /src/components/navbar.jsx
/src/components/listPage.jsx
src/A…目录
扩展学习资料
State进阶知识点
状态更新扩展
shouldComponentUpdate
PureComponent
为何使用不变数据【保证数据引用不会出错】 单一数据源 /src/App.js
/src/components/listItem.jsx
状态提升 /src/components/navbar.jsx
/src/components/listPage.jsx
src/App.js
有状态组件无状态组件
Stateful【有状态】和Stateless【无状态】的区别
Stateful
Stateless
小结
练习 扩展学习资料 预习资料名称 链接 备注 不可变数据 https://github.com/immutable-js/immutable-js 无 JS内存管理 内存管理 - JavaScript | MDN 无 状态提升 mangojuice.top - 该网站正在出售 - mangojuice 资源和信息。 扩展阅读 context管理状态 http://react.html.cn/docs/context.html 聊一聊我对 React Context 的理解以及应用 - 掘金 扩展阅读
State进阶知识点
通过条件判断优化渲染使用不可变数据状态提升使用无状态组件
状态更新扩展
阻止不必要的render方法执行
shouldComponentUpdate
// render渲染执行前调用的函数,返回false,可以有效的阻止不必要的render方法执行shouldComponentUpdate(nextProps, nextState) {console.log(props, this.props, nextProps);console.log(state, this.state, nextState);if(this.state.count nextState.count) {return false}if(this.props.id nextProps.id) {return false}return true}
PureComponent
import React, { PureComponent } from react;
class ListItem extends PureComponent {}
为何使用不变数据【保证数据引用不会出错】
// ...
handleDelete (id) {// 使用不可变数据, filter返回一个新数组const listData this.state.listData.filter((item) item.id ! id);this.setState({listData,});};handleAmount () {// 如不使用新的数组【没有使用不可变数据】, state变化不会重新渲染UI//const _list this.state.listData.concat([]);/* pop() 方法用于删除数组的最后一个元素并返回删除的元素。注意此方法改变数组的长度提示 移除数组第一个元素请使用 shift() 方法。*/_list.pop();this.setState({listData: _list,});};
// ...
如下图如果没有创建新的引用在PureComponent中不会调用render 如下图使用不可变数据可以避免引用带来的副作用使得整个程序数据变的易于管理 单一数据源
handleReset () {// 使用map方法创建一个新的数组const _list this.state.listData.map((item) {// ... 解构符const _item { ...item };_item.value 0;return _item;});this.setState({listData: _list,});// 此时props数据变化子组件state.count没变化// 原因出在没有使用单一数据源}; /src/App.js
import React, { PureComponent } from react;
import ListItem from ./components/listItem;
import ListItemFunc from ./components/listItemFunc;
import style from ./components/listitem.module.css;// eslint-disable-next-line no-unused-vars
class App extends PureComponent {constructor(props) {super(props);this.state {listData: [{id: 1,name: sony 65寸高清电视,price: 4000,stock: 1,value: 4,},{id: 2,name: 华为 Meta30,price: 6000,stock: 12,value: 2,},{id: 3,name: 华硕 玩家国度笔记本,price: 10000,stock: 11,value: 1,}],};}renderList() {return this.state.listData.map((item) {return (ListItemkey{item.id}data{item}onDelete{this.handleDelete}onDecrease{this.handleDecrease}onAdd{this.handleAdd}/);});}handleDelete (id) {// 使用不可变数据, filter返回一个新数组const listData this.state.listData.filter((item) item.id ! id);this.setState({listData,});};handleDecrease (id) {// 使用不可变数据, filter返回一个新数组const _data this.state.listData.map((item) {if (item.id id) {const _item { ...item };_item.value--;if (_item.value 0) _item.value 0;return _item;}return item;});this.setState({listData: _data,});};handleAdd (id) {// 使用不可变数据, filter返回一个新数组console.log(id);const _data this.state.listData.map((item) {if (item.id id) {const _item { ...item };_item.value;return _item;}return item;});this.setState({listData: _data,});};handleAmount () {// 如不使用新的数组【没有使用不可变数据】, state变化不会重新渲染UI//const _list this.state.listData.concat([]);/* pop() 方法用于删除数组的最后一个元素并返回删除的元素。注意此方法改变数组的长度提示 移除数组第一个元素请使用 shift() 方法。*/_list.pop();this.setState({listData: _list,});};handleReset () {// 使用map方法创建一个新的数组const _list this.state.listData.map((item) {// ... 结构符const _item { ...item };_item.value 0;return _item;});this.setState({listData: _list,});// 此时props数据变化子组件state.count没变化// 原因出在没有使用单一数据源};render() {return (div classNamecontainerbutton onClick{this.handleAmount} classNamebtn btn-primary减去最后一个/buttonbutton onClick{this.handleReset} classNamebtn btn-primary重置/button{this.state.listData.length 0 (div classNametext-center购物车是空的/div)}{this.renderList()}/div);}
}export default App;
/src/components/listItem.jsx
// import React, { Component } from react;
import React, { PureComponent } from react;
import style from ./listitem.module.css;
import classnames from classnames/bind;
const cls classnames.bind(style);
class ListItem extends PureComponent {// 类的构造函数// eslint-disable-next-line no-useless-constructorconstructor(props) {super(props);} render() {console.log(item is rendering);return (div classNamerow mb-3div classNamecol-4 themed-grid-colspan style{{ fontSize: 22, color: #710000 }}{this.props.data.name}/span/divdiv classNamecol-1 themed-grid-colspan className{cls(price-tag)}{this.props.data.price}/span/divdivclassName{col-2 themed-grid-col${this.props.data.value ? : -s}}buttononClick{() {this.props.onDecrease(this.props.data.id);}}typebuttonclassNamebtn btn-primary-/buttonspan className{cls(digital)}{this.props.data.value}/spanbuttononClick{() {this.props.onAdd(this.props.data.id);}}typebuttonclassNamebtn btn-primary/button/divdiv classNamecol-2 themed-grid-col¥ {this.props.data.price * this.props.data.value}/divdiv classNamecol-1 themed-grid-colbuttononClick{() {this.props.onDelete(this.props.data.id);}}typebuttonclassNamebtn btn-danger btn-sm删除/button/div/div);}
}
export default ListItem;
状态提升
处理组件和子组件数据传递自顶向下单向流动 /src/components/navbar.jsx
import React, { PureComponent } from react;
class Nav extends PureComponent {render() {return (nav classNamenavbar navbar-expand-lg navbar-light bg-lightdiv classNamecontainerdiv classNamewrapspan classNametitleNAVBAR/spanspan classNamebadge badge-pill badge-primary ml-2 mr-2{this.props.itemNum}/spanbuttononClick{this.props.onReset}classNamebtn btn-outline-success my-2 my-sm-0 frtypebuttonReset/button/div/div/nav);}
}
export default Nav;
/src/components/listPage.jsx
import React, { PureComponent } from react;
import ListItem from ./listItem.jsx;
// 商品列表渲染
class ListPage extends PureComponent {renderList() {return this.props.data.map((item) {return (ListItemkey{item.id}data{item}onDelete{this.props.handleDelete}onDecrease{this.props.handleDecrease}onAdd{this.props.handleAdd}/);});}render() {return (div classNamecontainer{this.props.data.length 0 (div classNametext-center购物车是空的/div)}{this.renderList()}/div);}
}
export default ListPage;
src/App.js
import React, { PureComponent } from react;
import Nav from ./components/navbar;
import ListPage from ./components/listPage;
const listData [{id: 1,name: sony 65寸高清电视,price: 4000,stock: 1,value: 4,},{id: 2,name: 华为 Meta30,price: 6000,stock: 12,value: 2,},{id: 3,name: 华硕 玩家国度笔记本,price: 10000,stock: 11,value: 1,},
];
// eslint-disable-next-line no-unused-vars
class App extends PureComponent {constructor(props) {super(props);this.state {listData: listData,};}handleDelete (id) {// 使用不可变数据, filter返回一个新数组const listData this.state.listData.filter((item) item.id ! id);this.setState({listData,});};handleDecrease (id) {// 使用不可变数据, filter返回一个新数组const _data this.state.listData.map((item) {if (item.id id) {const _item { ...item };_item.value--;if (_item.value 0) _item.value 0;return _item;}return item;});this.setState({listData: _data,});};handleAdd (id) {// 使用不可变数据, filter返回一个新数组console.log(id);const _data this.state.listData.map((item) {if (item.id id) {const _item { ...item };_item.value;return _item;}return item;});this.setState({listData: _data,});};handleAmount () {// 如不使用新的数组【没有使用不可变数据】, state变化不会重新渲染UI//const _list this.state.listData.concat([]);/* pop() 方法用于删除数组的最后一个元素并返回删除的元素。注意此方法改变数组的长度提示 移除数组第一个元素请使用 shift() 方法。*/_list.pop();this.setState({listData: _list,});};handleReset () {// 使用map方法创建一个新的数组const _list this.state.listData.map((item) {// ... 结构符const _item { ...item };_item.value 0;return _item;});this.setState({listData: _list,});// 此时props数据变化子组件state.count没变化// 原因出在没有使用单一数据源};render() {return (Nav itemNum{this.state.listData.length} onReset{this.handleReset} /ListPagedata{this.state.listData}handleAdd{this.handleAdd}handleAmount{this.handleAmount}handleDecrease{this.handleDecrease}handleDelete{this.handleDelete}handleReset{this.handleReset}//);}
}
export default App;
有状态组件无状态组件
Stateful【有状态】和Stateless【无状态】的区别
Stateful
类组件有状态组件容器组件
Stateless
函数组件无状态组件展示组件
尽可能通过状态提升原则将需要的状态提取到父组件中而其他的组件使用无状态组件编写【父组件有状态子组件无状态】
无状态组件简单好维护单一从上而下的数据流
小结
优化渲染使用不可变数据单一数据源以及状态提升无状态组件写法
练习
【题目1】 用单一数据源原则和状态提升原则改造购物车工程
【题目2】 目前Header中显示的是商品种类数量改造成商品的总数目