1.基本语法(jsx)
代码语言:javascript复制const name="小明";
const getName = () => {
return "小明"
}
const element = <h1>Hello, world!</h1>;
// 嵌入变量
const element = <h1>Hello, {name}</h1>;
// 嵌入表达式
const element = <h1>Hello, {getName()}</h1>;
注意:在点击事件中,不要直接调用函数,如果需要传递参数,使用箭头函数,jsx中所有dom事件必须用驼峰命名。如下:
代码语言:javascript复制const a = <a onClick={() => this.handleClick(params)}>点击</a>
1.1. 条件渲染
代码语言:javascript复制function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
1.2. 循环渲染
代码语言:javascript复制const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
2.组件
react中所有的东西都是组件,从定义类型组件分为函数式组件和class组件两种,从功能上区分又有容器组件和ui组件,根据表单相关又可以分为受控组件和非受控组件,更高级的组件用法还有高阶组件等。
react时单向数据流,数据只能从父组件传递给子组件,子组件通过props参数获取父组件传递的内容。
2.1.函数式组件
代码语言:javascript复制function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
2.2.class组件
代码语言:javascript复制class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
2.3.容器组件
负责处理业务逻辑
代码语言:javascript复制//容器组件
class TodoListContainer extends React.Component{
constructor(props){
super(props);
this.state = {
todos:[]
}
this.fetchData = this.fetchData.bind(this);
}
componentDidMount(){
this.fetchData();
}
fetchData(){
fetch('/api/todos').then(data =>{
this.setState({
todos:data
})
})
}
render(){
return (
<div>
<TodoList todos={this.state.todos} />
</div>
)
}
}
2.4.UI组件
只负责展示
代码语言:javascript复制//展示组件
class TodoList extends React.Component{
constructor(props){
super(props);
}
render(){
const {todos} = this.props;
return (
<div>
<ul>
{todos.map((item,index)=>{
return <li key={item.id}>{item.name}</li>
})}
</ul>
</div>
)
}
2.5.受控组件
React 的 state 为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
代码语言:javascript复制class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('提交的名字: ' this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
名字:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="提交" />
</form>
);
}
}
2.6.非受控组件
表单数据将交由 DOM 节点来处理
代码语言:javascript复制class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef();
}
handleSubmit(event) {
alert('A name was submitted: ' this.input.current.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
2.7.高阶组件
高阶组件主要用来处理组件直接按可复用的逻辑,将可复用的部分抽离出来,供其余组件使用。
高阶组件是参数为组件,返回值为新组件的函数
代码语言:javascript复制const EnhancedComponent = higherOrderComponent(WrappedComponent);
详情请参考react官网 高阶组件教程
3.组件生命周期
3.1.挂载
当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:
- constructor()
- static getDerivedStateFromProps()
- render()
- componentDidMount() ---通常在此生命周期获取后端数据
3.2.更新
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:
- static getDerivedStateFromProps()
- shouldComponentUpdate() ---常用于代码优化
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
3.3.图解
4.setState详解
setState() 将对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式。
4.1. 基本用法和参数
setState有两个参数,第一个是要更新的内容,可以是对象或者函数,第二个参数是回调函数更新完成后的操作可以写在回调函数中。
1)第一参数为对象
代码语言:javascript复制this.setState({quantity: 2})
2)第一参数为函数
代码语言:javascript复制this.setState((state, props) => {
return {counter: state.counter props.step};
});
setState() 的第二个参数为可选的回调函数,它将在 setState 完成合并并重新渲染组件后执行。通常,我们建议使用 componentDidUpdate() 来代替此方式。
4.2 setState()执行后发生了什么?
- static getDerivedStateFromProps()
- shouldComponentUpdate() ---返回true则继续往下执行,返回false将不继续执行
- render()
- getSnapshotBeforeUpdate()
- componentDidUpdate()
5.路由基础
react-router官网
react路由升级到v4版本之后(目前已经到v5),路由直接集成到DOM结构中,最常用的路由组件有:
代码语言:javascript复制 // 相当于a标签的功能
<Link to="/">Home</Link>
// 路由容器,传入组件后,匹配到路由就会渲染对应组件
<Route exact path="/" component={Home} />
<Redirect to="/somewhere/else" />
// 单页应用路由组件要包含整个项目最大的容器
<Router>
<App />
</Router>
// 使用switch将Route或者Redirect包起来之后,智慧渲染第一个匹配路由的组件
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>
</Switch>
关于每个路与组件详细的api介绍,请参考react-router官网
- React周边
- Antd -- ui组件库
- Material-UI -- ui组件库
- Redux -- 状态管理
- Mobx -- 状态管理
- React-Router --路由
- Ant Design Pro -- 后台管理系统最佳实践
- 社区精选组件