1. react是声明式开发,以往是命名式开发
  2. 可以与其它框架并存,因为只会挂载到root节点中
  3. 组件化
  4. 单向数据流
  5. 函数式编程

组件

  1. React.component是基类,继承了该基类的类就是一个组件
    通过ReactDOM.render(<App />,document.getElementById('root'));其中,就是JSX语法。
    1
    2
    3
    class App extends React.Component{
    render();
    }
  2. render(){}函数 定义组件的内容。
  3. 组件的定义,组件是页面的一部分。ReactDOM只能渲染单标签,所以如果是多个标签,可以使用 ReactDOM.render(<div><App /><Test /></div>,document.getElementById("root")); 一个div标签包裹。

JSX语法

有两种类型的标签。
一种是普通的html标签,首字母小写;二种是组件标签,首字母大写。

1
2
3
import {Fragment} from 'react'
<Fragment>...<Fragment>
//解决了在根目录渲染必须要使用div包裹

数据驱动的设计思想和事件绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class TodoList extends Component {
constructor(props) {//固定写法,获取基类属性
super(props);//固定写法,获取基类属性
this.state = {//固定写法,数据存储
inputValue: 'hello world',
list: []
}
}
handleInputChange(e) {
this.setState({//修改state中的值的固定写法
inputValue: e.target.value
})
}
render() {
return (
<Fragment>
<input type="text"
value={this.state.inputValue}
onChange={this.handleInputChange.bind(this)}//事件响应on+Change(大写开头),bind改变this指向
/>
<ul>
<li>learn React</li>
<li>learn Component</li>
</ul>
</Fragment>
);
}
}

数组循环

1
2
3
this.state.list.map((value,index) => {//遍历list
return <li key={index}>{value}</li>
})

Jsx注释

1
{/* jsx注释 写法 */}

JSX属性命名

  1. class => className
  2. for(label) => htmlFor
  3. 1
    dangerouslySetInnerHTML={{ __html: value }} 对value的html内容不进行转义直接输出如<div>123</div>

父子组件传值

父组件通过属性的形式向子组件传值
子组件想要和父组件通信,他要调用父组件传递过来的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//父
import TodoItem from './TodoItem'
getListItems() {
return this.state.list.map((value, index) => {
return (
<TodoItem
content={value}
key={index}
deleteFunction={this.handleItemClick}
></TodoItem>
)
})
}
//子
render() {
const { content } = this.props.content;//简略写法,或者写在constructor里面
return (
<li onClick={this.handleItemClick}>
{this.content}

</li>
)
}

Props, State 与 render 函数

props 属性
state 指组件中的数据
render 函数:用来渲染组件中的内容。
三者关系:
render 函数什么时候执行?

  1. 组件第一次渲染的时候,会被默认执行一次。
  2. 当state数据发生变更的时候,render函数就会被重新执行一次。
  3. 当props数据发生变化的时候,render函数就会被重新执行一次。

ref

react中ref的使用:react中操作dom。获取原声标签对应的dom节点。
<button ref={(button)=>{this.buttonElem = button}}></button>
在点击函数中添加 console.log(this.buttonElem.clientTop);
注意:ref写在html标签上获取的是dom节点。写在组件标签上,获取的是组件的js实例。
setState是异步的。
同步写法:

1
2
3
4
5
6
this.setState(
()=>{
return {counter:newCounter}
},
()=>{console.log(this.divElem.innerHTML)
});

生命周期

life cycle

shouldComponentUpdate函数存在的意义在于:当state中的数据发生变化,但并不需要页面重新渲染,即并不需要重新触发render函数,可以在shouldComponentUpdate中设置return false,之后的rendercomponentWillUpdate,componentDidUpdate函数,就都不会执行了。
这样数据发生变化,就不需要重新渲染,可以提高组件的性能。

componentDidMount中添加事件绑定
componentWillUnmount中移除事件绑定

axios

npm install axios --save
如果只在开发环境下运行,那么执行 –save -dev

1
2
3
4
5
6
import axios from 'axios'
componentDidMount() {
window.addEventListener("click", this.handleClickWindow);
const promise = axios.get('http://www/dell-lee.com/react/api/demo.json');
promise.then((res)=>{console.log(res.data)});//data - success -true
}

Ant Design

npm install antd --save

index.js添加import 'antd/dist/antd.css'

react-router

npm install react-router-dom

import { BrowserRouter as Router, Route, Link } from "react-router-dom";

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { BrowserRouter as Router, Route } from "react-router-dom";
import Father from './Father';
import Antd from './Antd';
class Entry extends Component {
render() {
return (
<Router>
<div>
<Route path="/father" component={Father}></Route>
<Route path="/antd" component={Antd}></Route>
</div>
</Router>
)
}
}
ReactDom.render(<Entry></Entry>,document.getElementById('root'));

//antd
import {Button} from 'antd';
import {Link} from 'react-router-dom'
export class Antd extends Component {
render() {
return (
<Link to='./father'>//跳转到father
<Button type="default">123</Button>
</Link>
)
}
}
export default Antd

带参数

Button上,使用link,访问'/list/123'

1
2
3
<Link to='/list/123'>
<Button type='primary'>按钮</Button>
</Link>

index.js上,
<Router path='/list/:id' component={NewList}>
list.js上,就可以使用
this.props.match.params.id获取到这个值。

withRouter

作用:把不是通过路由切换过来的组件中,将react-routerhistory、location、match 三个对象传入props对象上

 默认情况下必须是经过路由匹配渲染的组件才存在`this.props`,才拥有路由参数,才能使用编程式导航的写法,执行`this.props.history.push('/detail')`跳转到对应路由的页面,然而不是所有组件都直接与路由相连(通过路由跳转到此组件)的,当这些组件需要路由参数时,使用`withRouter`就可以给此组件传入路由参数,此时就可以使用`this.props`