1、jsx
1、语法糖:React.createElement(component, props, …children) 函数的语法糖
3、引入库:JSX 会编译为 React.createElement 调用形式,所以 React 库也必须包含在 JSX 代码作用域内
4、点语法来引用一个 React 组件。当你在一个模块中导出许多 React 组件时,这会非常方便。例如,如果 MyComponents.DatePicker 是一个组件
5、 解析组件:HTML 内置组件, 会生成相应的字符串 ‘div’ 或者 ‘span’ 传递给 React.createElement。自定义的组件,如 会编译为 React.createElement(Foo)。
6、通用表达式:如果你想通过通用表达式来(动态)决定元素类型,你需要首先将它赋值给大写字母开头的变量
7、props:它的默认值是 true,<Greeting {…props} />;展开运算符 … 来在 JSX 中传递整个 props 对象
8、props.包含在开始和结束标签之间的 JSX 表达式内容, 会移除行首尾的空格以及空行。与标签相邻的空行均会被删除,文本字符串之间的新行会被压缩为一个空格,
JavaScript 表达式可以被包裹在 {} 中作为子元素,渲染 HTML 列表,
替代模板字符串,
return
布尔:
false, null, undefined, and true 是合法的子元素。但它们并不会被渲染
要解决这个问题,确保 && 之前的表达式****总是布尔值:
2、元素渲染
1、元素是构成 React 应用的最小砖块。
2、React 元素是创建开销极小的普通对象。React DOM** 会负责更新 DOM 来与 React 元素保持一致
3、渲染到根结点:想要将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render():
4、更新:React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。一个元素就像电影的单帧:它代表了某个特定时刻的 UI。
根据我们已有的知识,更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()。
组件挂载部分
- getdefaultprops,设置组件默认属性,在coustructor里面执行
- 组建渲染之前:componentWillMount。会在构造函数和state初始化后,执行。之后是组件挂载,render解析
- 组建渲染之后:componentDidMount
数据更新部分
- 组件可否更新:shouldComponentUpdate,,两个参数,nextprops是父组件传递给自组件的,nextstate是更新之后的
3、组件和props
1、组件
UI 拆分为独立可复用的代码片段,类似于 JavaScript 函数。它接受入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
2、渲染过程
我们调用 ReactDOM.render() 函数,并传入 作为参数。
React 调用 Welcome 组件,并将 {name: ‘Sara’} 作为 props 传入。
Welcome 组件将 元素作为返回值。
React DOM 将 DOM 高效地更新
3、提取组件
如果 UI 中有一部分被多次使用(Button,Panel,Avatar),或者组件本身就足够复杂(App,FeedStory,Comment),那么它就是一个可提取出独立组件的候选项。
4、纯函数
这样的函数被称为“纯函数”,因为该函数不会尝试更改入参,且多次调用下相同的入参始终返回相同的结果。
5、render过程
当 被传给 ReactDOM.render()的时候,React 会调用 Clock 组件的构造函数。
初始化 this.state。我们会在之后更新 state。
之后 React 会调用组件的 render() 方法。
这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配 Clock 渲染的输出。
当 Clock 的输出被插入到 DOM 中后,React 就会调用 ComponentDidMount()
Clock 组件会通过调用 setState() 来计划进行一次 UI 更新。
重新调用 render() 方法来确定页面上该显示什么。这一次,render() 方法中的 this.state.date 就不一样了,如此以来就会渲染输出更新过的时间。React 也会相应的更新 DOM。
一旦 Clock 组件从 DOM 中被**移除,**React 就会调用 componentWillUnmount() 生命周期方法,这样计时器就停止了。
6、state异步更新
- 出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。
因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
2、要解决这个问题,可以让 setState() 接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
3、当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。
4、这里的合并是浅合并,所以 this.setState({comments}) 完整保留了 this.state.posts, 但是完全替换了 this.state.comments。
7、数据流
5、组件可以选择把它的 state 作为 props 向下传递到它的子组件中:
但是组件本身无法知道它是来自于 Clock 的 state,或是 Clock 的 props,还是手动输入的:
8、事件处理
1、区别
React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
在 React 中另一个不同点是你不能通过返回 false 的方式阻止默认行为。你必须显式的使用 preventDefault 。
该元素初始渲染的时候添加监听器即可
2、this
如果觉得使用 bind 很麻烦,这里有两种方式可以解决
handleClick = () => {
console.log(‘this is:’, this);
}
onClick={() => this.handleClick()}>
3、传递参数
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row
<button onClick={this.deleteRow.bind(this, id)}>Delete Row
shouldComponentUpdate(nextProps,nextState){
console.log('01是否要更新数据')
console.log(nextProps) //父组件传给子组件的值,这里没有会显示空
console.log(nextState) //数据更新后的值
return true; //返回true,确认更新
}
-
更新之前执行:componentWillUpdate,返回true,会执行,接着render会渲染
-
更新之后执行:componentDidUpdate
-
props改变之前执行:
-
componentWillreceiveProps,父组件给子组件传递的值发生改变后调用,接受父组件给子组件传递的值,判断新旧有没有发生改变
componentWillReceiveProps(nextProps){
if(this.props.data.photo != nextProps.data.photo){
this.setState({
logoUrl: nextProps.data.photo
})
}
}
- **
组件卸载之前执行:componentWillUnmount
**
10.
方法props传递
1、父组件在子组件上定义方法属性,和普通属性一样
2. 方法传值调用父组件的方法,子组件调用this,props.fun()
关于setstate是同步还是异步
3.
条件渲染
- 需求,设置一个flag属性,如果是true,就返回登陆,如果是false,就是注册。
- 组件:1、构造函数中,初始化flag。2、事件函数中,修改flag。3、render中,判断flag,返回不同的值。4、注意:{}里面1的变量,可以是html标签,就是变量的值可以是html标签
条件渲染的四种方式:1、表达式,适用于二选一,2、&&符,适用于一个组件要不要渲染,3、变量存储,适用于多个组件。4、函数渲染,适用于多组件多条件
列表渲染
- 作用:用于遍历后端返回的数据
render(){
return (
<div>
<ul>
this.state.list.**map((value,index)**=>{
return (
<li **key={index}**>
<span>value.name</span>
<span>value.sex<span>
<div>
value.job.map((v,i)=>{
return <span key={index}>{v}</span>
})
</div>
</li>
)
})
</ul>
</div>
)
}
- 注意点:map遍历,返回的列表记得加key
- 注意点:变量用{ index }包裹
数组和返回值
- push,unshift返回数组长度
- pop,shift返回删除元素
- reverse返回改变后的数组
- a.concat(b)不改变原数组,返回拼接后的数组
- slice不改变原数组,返回截取的数组
- splice改变原数组,返回改变后的数组
key的作用
- 索引不变,不用重新渲染,索引变化,ui重绘
//删除
let del=[1,2,3,4]
del.splice(1,2) //删除从第1项开始后的两项
del//[1,4]
//插入
let add=[1,2,3]
add.splice(2,0,1) //删除从第二项开始的0个字符并插入1
add//[1,2,1,3]
//替换
let chan=[1,2,3,4]
chan.splice(2,1,5)
chan //[1,2,5,4]
let a=[1,2,3,4,5]
a.forEach(x=>{
console.log(x)
})
let a=[1,2,3,4,5]
a.map(x=>x+1)
//[2,3,4,5,6]
let a=[1,2,3,4,5]
a.filter(x=>x>3)
//[4,5]
let a=[1,2,3,4,5]
a.every(x=>x<6)
//true
a.every(x=>x>2)
//false
let a=[1,2,3,4,5]
a.some(x=>x<2)
//true
//格式
Array.reduce((pre,next,index,array)=>{
},[number])
//例
let a=[1,2,3,4,5]
a.reduce((pre,next,index,array)=>{
return pre+next
})
//15
受控组件
就是input里面的value值来自于state控制,并且使用onchang来处理state。
- input 里面的value={this.state.value}。
- input组件添加事件 onchang={this.onchanghandler}。用于处理state
- e传递过来,setstate(value:e.traget.value)。
- 表单事件会默认跳转,所以在change里面阻止默认事件,e.preventdefalut()放在提交按钮事件里面
- 很麻烦,为每一个input编写事件处理函数
非受控组件
- 数据较多使用
- 类似于传统的html表单
- 数据本身由dom处理,输入就可以显示最新值,受控组件输入后值是由react控制显示的
- 会使用ref获取dom元素,进而获取值
ref和dom
- 管理媒体动画
- 集成第三方dom,比如获取非受控组件的值。
Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们。
<div ref={this.myref}
//在constructro里面初始化dom
this.ref = React.createRef()
//然后在componentDidUpdate里面获取dom
this.ref.current.style.color="red"
非受控组件就是给每个input组件添加一个ref属性,获取value时采用obj.value
状态提升
- 如果子组件有相同的state,就把state提升到父组件,然后当作参数传递到子组件
class Input extends React.Component {
constructor(props) {
super(props)
// 数据可以不再保存在子组件的 state 当中
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
// 通过 props 获取父组件的 setState(修改数据的方法)
// 传入一个参数(新的数据)
this.props.onContentChange(e.target.value)
}
render() {
// 通过 props 获取父组件的 state(数据)
return (
<input type='text' value={ this.props.content } onChange={ this.handleChange } />
)
}
}
组合和继承
//父组件里面
return(
<div>
<component>
<div>我是组合组件</div>
</cimponent>
</div>
)
然后在component里面可以读取到**{this.props.children}**会读取到里面的div
propType类型验证
1、组件类的属性proptype
2、定义一个属性对象
3、proptype.类型.isrequired
4、默认值属性defaultprops
5、
//限制属性
mycomponent.PropType={
title: PorpType.number.isrequired
}
//默认值
mycomponent.defaultprops={
name:"jukeke"
}
//限制单个元素
children:PropType.element.isrequired
MyComponent.propTypes = {
// 你可以将属性声明为 JS 原生类型,默认情况下
// 这些属性都是可选的。
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
// 任何可被渲染的元素(包括数字、字符串、元素或数组)
// (或 Fragment) 也包含这些类型。
optionalNode: PropTypes.node,
// 一个 React 元素。
optionalElement: PropTypes.element,
// 一个 React 元素类型(即,MyComponent)。
optionalElementType: PropTypes.elementType,
// 你也可以声明 prop 为类的实例,这里使用
// JS 的 instanceof 操作符。
optionalMessage: PropTypes.instanceOf(Message),
// 你可以让你的 prop 只能是特定的值,指定它为
// 枚举类型。
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// 一个对象可以是几种类型中的任意一个类型
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 可以指定一个数组由某一类型的元素组成
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// 可以指定一个对象由某一类型的值组成
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// 可以指定一个对象由特定的类型值组成
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// An object with warnings on extra properties
optionalObjectWithStrictShape: PropTypes.exact({
name: PropTypes.string,
quantity: PropTypes.number
}),
// 你可以在任何 PropTypes 属性后面加上 `isRequired` ,确保
// 这个 prop 没有被提供时,会打印警告信息。
requiredFunc: PropTypes.func.isRequired,
// 任意类型的数据
requiredAny: PropTypes.any.isRequired,
// 你可以指定一个自定义验证器。它在验证失败时应返回一个 Error 对象。
// 请不要使用 `console.warn` 或抛出异常,因为这在 `onOfType` 中不会起作用。
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
},
// 你也可以提供一个自定义的 `arrayOf` 或 `objectOf` 验证器。
// 它应该在验证失败时返回一个 Error 对象。
// 验证器将验证数组或对象中的每个值。验证器的前两个参数
// 第一个是数组或对象本身
// 第二个是他们当前的键。
customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
};
antd
- 按需加载
import button from 'antd/es/button'
import 'antd/es/button/style/css'
- 配置文件
1、npm run eject 去拉去react的配置文件
2、如果文件修改了,就删除git文件夹,可以 正常访问。
3、安装依赖,npm install babel-plugin-import -D
4、配置package.json 复制依赖过去
react fetct
1、fetch的参数是一个字符串,表示要访问的网址,获取从网址返回的数据
2、fecth是基于promise的
3、使用then接受res表示正确
1、发送post的时候指定headers和body
2、headers有content-type和accept
3、body需要用stringify将对象变成字符串
跨域:
开发模式下:
react:
在package.json文件中,添加如下参数
“proxy”: “http://localhost:8088”
1、单向跨域:所有请求发送到同一地址
2、对象的属性:
"proxy":{
所有请求地址带api的都会代理到target路径下面
"/api":{
"target":"http://m.kugo.com",
"changeOrigin": true
要不要把请求头的host设置为代理地址
"pathRewrite": {
重写路径
'^/api': '',
},
}
}
手动配置跨域
1、创建node服务器
2、编写路由文件
3、服务器引入路由文件然后运行
安装插件跨域
封装getpost网络请求
1、配置http文件
2、配置api,记得导出
api的入口文件
路由
安装react-router-dom
标签使用
1、标签router
2、属性:path,组件的路径,component组件对象作为值
hashrouter和browserrouter
link链接
精确匹配路径
switch和404页面
render代替component
链接高亮
参数传递
读取问号参数
navlink属性
重定向
push和replac
withrouter
promot
路由嵌套