使用React的语法格式写JavaScript代码,该代码的目的是写网页的标签内容,同写原生的HTML没有本质的区别,但原生的HTML更新DOM,节点内容,动态样式等会很不方便,React在这些以及其他更多方面会有优势。
jsx就是将html标签写在js的变量中,这样js和html就融合在了一起形成了jsx,那只是单纯的变量如函数作用域下的变量就是普通的React元素,如果该变量是个函数的返回值或类的render()方法的返回值,则该变量是个React组件。
React其实就是写HTML标签到网页上的,那它怎么写呢:
React运行时首先会根据返回的JSX创建对应的Element,用以描述UI界面。然后通过Element则会对应创建组件实例Instance,也就是我们所说的Virtual Dom,最后通过Virtual Dom去映射真实的浏览器环境。在首次渲染之后,后序的更新Reac只需要找到(Reconciler)两次Virtual Dom的差异性(diff),然后通过diff去更新真实DOM,这样就实现了增量更新真实DOM,毕竟DOM的操作是非常昂贵的。
纯函数不会改变传入的参数,react 组件也不会改变props,组件拥有自己的状态用来保存数据
react组件第一次加载到DOM中,叫挂载,react组件生成的DOM被移除时,叫卸载,会对应有生命周期钩子函数
组件的状态可以以props的方式传递给子组件,这叫做单向数据流
Redux将所有的数据(如state)保存在一个容器中(store)
store保存所有对象的状态,ui组件可以直接从store访问到特定对象的状态
ui组件改变状态,分发一个action(就是将可执行信息发送到store)
当store收到action后将这个action代理给相关的reducer
reducer是个纯函数,它可以查看之前的状态,执行一个action并返回一个新的状态。
组件访问store中的state,组件发起一个action,用于改变store中的state
store处理action,让reducer去处理,reducer处理后更新state,state更新,组件重新渲染。
本来刚学React的时候学状态管理是学它的,后来公司不用,用Mobx,尴尬只有去学Mobx了,但Redux的思想还是有点价值的:)
props
给类组件添加默认的props,如果在调用该组件时没有传递props,则使用props时会用默认值
class Person extends Component {
render () {
const { name, age, child } = this.props;
console.log(name, age, child);
return <div></div>
}
}props的默认值类型可以为js基本类型,引用类型,React元素等
Person.defaultProps = { name: 'name', age: 18, child: <span>child</span>}React元素:
描述了你希望在屏幕上看到的内容
const app = <div>App</div>函数组件:
function App(props) {return (<div>{props.name}</div>)}类组件
class App extends React.Component {
componentDidMount () {}
componentWillUnmount () {}
render () {
return (
<div>{this.props.name}</div>
)
}
}
出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用
因为 this.props 和 this.state 可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
this.setState((state, props) => ({
counter: state.counter + props.counter
}))
不传参数时定义事件的处理方法
handleClick = (e) => {
}
传参时:
handleClick (x, y, e) {}
render () {return (<div onClick={this.handleClick.bind(this, id, name)}></div>)}
条件渲染:
render () {
return (
{this.state.show &&
<div>{ this.state.show }</div>
}
)
}
render () {
return (
<div>
{isShow ? (
<button>show</button>
) : (
<button>not show</button>
)
</div>
)
}
render () {
return (
{!this.props.warn && null}
)
}
循环渲染:
render () {
return (
{this.props.list.map(item, index) =>
<div key={index}>
<h3></h3>
<div></div>
</div>
}
)
}
受控组件:
<select value={this.state.value} onChange={this.handleChange}>
<option value='red'>red</option>
<option value='yellow'>yellow</option>
状态提升
将需要共同修改或渲染的状态提升到共同的父组件中,修改该状态调用父组件传递的props中的方法
无障碍辅助功能是使得辅助技术正确解读网页的必要条件。
aria-* HTML 属性
语义化的 HTML
Fragments
import React, { Fragments } from 'react';render () {return ({this.state.list.map(item =><Fragments key={item.id}><div></div><h2></h2></Fragments>)}短语法:render () {return (<><div></div><div></div></>)}获取dom结构
class App extends React.Component { constructor (props) { super(props); this.inputInstance = React.createRef(); }focus () {// current获取 DOM 节点this.inputInstance.current.focus();}render () {<input ref={this.inputInstance} />}}父组件获取子组件的 DOM
function children (props) 『
class children extends React.Component {
}
mobx
@observer 的作用是组件使用了mobx的状态,当状态发生改变时,组件自动更新。
@observerclass Timer extends Component { render () { return ( ) }}@withRouter 的作用是给非路由匹配渲染的组件的props中添加路由参数:history,location,match,让它可以实现函数式导航