React02
React 进阶提升
条件渲染
- if条件渲染: 如果用户输入的金额>=10元, 购买成功
function BuySomething(props){
if(props.money >= 10){
return <p>恭喜, 购买成功! {props.money} >= 10</p>;
}
return <p> 购买失败,金额不足! {props.money}</p>
}
if (list.length % 2 === 0){
subTitle = <p>好记性不如烂笔头! </p>;
} else {
subTitle = <p>明日复明日, 明日何其多! </p>;
}
- && 连接符判断
{this.props.showTitle && (<h2>GTD 记事本</h2>)}
- 三目运算符判断
{/* 三目运算符/三元运算符 */}
{
list.length === 0 ?
<p>这里空空如也, 恭喜咯!</p> :
<ul>{list}</ul>
}
- 阻止组件渲染 (很少用到)
// 某种不希望渲染的条件发生了, 通过返回null阻止render渲染
if(true){
return null;
}
return (...);
受控组件*
在html中, input, select, textarea这些表单元素都会默认维护自己的状态,React通过受控组件
将用户输入的内容保存到state中,通过渲染表单组件,控制用户输入之后发生的变化。
//1. 在构造函数初始化状态
constructor(props) {
super(props);
this.state = { money:'' };
}
// 2.监听input的变化
<input type="text" value={this.state.money} onChange={this.handleChange} />
// 3.处理变化,更新state
handleChange = (e)=>{
// console.log(e.target.value);
this.setState({
money: e.target.value
})
}
状态提升*
如果有多个组件需要共享状态数据,把要MoneyInput共享的数据state={money, unit}提升到他们最近的共同父组件App中。
数据源要保证只有一个,并保持自上而下的数据流结构。
![](.\状态提升, 单位转换.png)
组件数据流
- 用户在MoneyInput组件中输入了数值
- 在input的onChange函数中,监听到了变化,把money传给父组件
- 父组件设置并更新到唯一的state中,状态提升完毕
- 因为this.setState被执行,故而render被重新触发, 根据unit,money转成不同的货币
- 父组件通过
money={rmb}
属性设置给MoneyInput组件,this.props.money
TODO-LIST
GTD软件: Getting things done
设置服务器端口
在package.json的scripts下配置
"start": "SET PORT=3456 & react-scripts start",
列表渲染
.map
可以帮我们把数组转换成元素的数列.filter
根据每个条目返回的boolean, 决定去留. true保留, false删除- 列表key注意:
- key的作用时在DOM中的元素被添加或移除时, 帮助react识别是哪些元素发生了变化
- 每个元素key需要是当前列表唯一的字符串, 一般使用id, 没有id时才使用index索引
- key要放在列表条目的根组件 (有嵌套时)
条目PropTypes检查类型
导包
import PropTypes from 'prop-types';
propTypes只在开发模式下进行检查,当给组件传入错误的值(或未传值),JS控制台会打印警告信息。在生产环境不会进行检查(影响页面效率)
属性类型及Required检查
/**
* 属性类型及isRequired检查
* order: 数字类型
* item: 字符串类型
*/
TodoItem.propTypes = {
order: PropTypes.number.isRequired,
item: PropTypes.string,
}
设置属性默认值(当父组件没有传入指定值时,使用默认值)
/**
* 设置属性默认值
*/
TodoItem.defaultProps = {
item: "默认的条目描述"
}
export & import
Refs 和 DOM
ref用来访问DOM节点或React元素 ref是reference的缩写
- 使用方式:
- 在组件得属性中添加
ref={(input) => {this.inputNode = input}}
- 在需要用其值或引用的地方通过
this.inputNode
即可
- 在组件得属性中添加
- 注意事项:
- ref在html元素上使用, ref的引用的是DOM节点
- ref在自定义的class组件上使用,ref的引用的是当前组件的实例
- ref不可以在函数式声明的组件上使用, 因为其没有实例,但是可以在内部使用ref
非受控组件*
- 如果希望表单数据由DOM处理,可以使用非受控组件方式。
- 常见的表单受控组件及 设置/获取 值方式如下:
元素 | 属性值 | 变化回调 | 在回调中获取值 |
---|---|---|---|
<input type="text" /> |
value="string" |
onChange |
event.target.value |
<input type="checkbox" /> |
checked={boolean} |
onChange |
event.target.checked |
<input type="radio" /> |
checked={boolean} |
onChange |
event.target.checked |
<textarea /> |
value="string" |
onChange |
event.target.value |
<select /> |
value="option value" |
onChange |
event.target.value |
在受控组件和非受控组件之间抉择:参考文档
如果表单的UI交互非常简单:通过refs实现非受控组件即可。
如果表单的UI交互比较复杂:官方推荐使用受控组件实现表单,把DOM节点/React元素的值或数据交给React组件处理(保存到state)。
路由
安装:
yarn add react-router-dom
导入Module:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
声明路由器及路由:
<Router>
<div>
<Route exact={true} path="/" render={() => (<TodoComponent showTitle={true} />)}/>
<Route path="/about" component={About}/>
</div>
</Router>
通过Link跳转
<Link to="/about">关于about</Link>
<Link to="/">主页Home</Link>
- 通过path声明路由路径;
exact={true}
表示严格匹配path- 通过component指定要渲染的组件;
- 通过render属性配合箭头函数,可以给组件传入属性参数。
- 通过Link的to属性指定要跳转的路径
组合
React提供了强大的组合模型,官方建议使用组合(而非继承)来复用组件代码。
包含
- 当一些组件不能提前知道他们的全部子组件是什么, 比如Dialog,Menu, Sidebar
- 通过组件内render声明
{props.children}
,使用时在标签内部填入自定义的元素内容即可。 - 通过自定义字段可以使组件拥有多个自定义元素入口。比如
subTitle
声明:
function AboutPanel(props) {
return (
<div className="about-panel">
<h2 className="about-title">{props.title}</h2>
{props.subTitle} <p>{props.desc}</p>
{props.children}
</div>
);
}
使用:
<AboutPanel
title="兴趣爱好"
desc="性别男, 爱好女。最大的缺点是太实诚,总爱习惯性给公司免费加班" >
<input type="text" ref={(input) => this.textInput = input}/>
<button onClick={() => alert(this.textInput.value)}>点评</button>
</AboutPanel>
特殊实例
// 这里AboutPanelSpcial 是 AboutPanel 的特殊实例
class AboutPanelSpcial extends React.Component{
render(){
return (
<AboutPanel
title="工作履历"
subTitle={<h5>人生精力丰富, 行业跨度大</h5>}
desc="走过男闯过北, 火车道上压过腿; 养过狼放过虎, 少林寺里练过武"
/>
)
}
}
三方UI设计语言
- 蚂蚁金服:https://ant.design/index-cn
- Material-UI:https://material-ui.com/
打包及发布
npm run build
运行服务器代码: build包含index.html文件的文件夹
前台运行: serve -s build
后台运行(指定端口80): nohup serve -s build -l 80 &
今天所有安装的包
react-router-dom 路由
应用场景:页面切换
安装方式:
yarn add react-router-dom
serve 开启服务
应用场景:部署打包好的应用
安装方式:
yarn global add serve
React02的更多相关文章
随机推荐
- 2017.9.17 HTML学习总结---table标签
接上: 2.1.3 HTML表单标签与表单设计 表单是用户与服务器交互的主要方法,用户在表单中输入数据,提交给服务器程序来处理. (1)表单的组成: 文本框(text),密码框(password), ...
- 2017.11.12 web中JDBC 方式访问数据库的技术
JavaWeb------ 第四章 JDBC数据库访问技术 在JavaWeb应用程序中数据库访问是通过Java数据库连接(JavaDateBase Connectivity简称JDBC)数据库的链接一 ...
- Mac 中显示资源库(Library)文件夹目录的几种方法
Mac中Library目录在10.6.7系统之后默认隐藏的,要想找到此文件夹有如下几种方法: 1. 用命令可以使其显示: 在终端中执行命令: chflags nohidden ~/Library ...
- CPP-STL:用vector保存对象时保存指针的优点, 以及reserve的使用(转)
代码1 #include <vector> #include <stdio.h> class A { public: A() { printf("A()/n" ...
- nuget打包
[1.创建.nuspec文件] 在.csproj目录下运行命令 nuget spec [2.生成包nupkg] 在.csproj目录下运行命令 nuget pack xxxx.csproj [推送命令 ...
- 根据值设置select的选中项
$('.selector').attr("checked", true); <s:iterator value="jobSelect" id=" ...
- C#继承的多态性
C#继承的多态性 当一个类A派生出新类B时,这个基类A在新类B中可以表现为不同的类型:用作它自己的类型.基类型,或者在实现接口时用作接口类型,我们将这种情况称为多态性. C#中的每种类型都是多态性的, ...
- C++ 编写的解码器小程序 map
c++ prime 5 ex11_4 代码如下 // ex11_4_word_transform.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&quo ...
- C#基础-hashtable,泛型和字典集合
hashtable 的存储方式 使用方法: 1.引入包含Hashtable的命名空间 using System.Collections; // 引入Hash所在的命名空间 2.往hash表里面添加数据 ...
- Python面向对象--高级(二)
## 使用__slots__限制类的属性 - 之前说到,可以通过在类外部实例或者类名任意定义实例属性或者类属性或者方法 class Person(object): pass Person.name = ...