安装脚手架
npm install create-react-app -g
create-react-app --version查看版本号3.31
create-react-app one
cd
create-react-app one
yarn start
文件
index.js入口文件
案例1(详解)
1.index.js引入子组件
import First from './index1';
2.index.js
ReactDOM.render(
// 通过属性传参,子组件通过params接收,相当于vue父子传参
<First name="李磊"></First>,
document.getElementById('root')
);
3.index1.js
//1.引入react
import React from 'react'//大写
// 2.创建无状态组件(函数组件)
// 3.元素变量
const html = <h2> 这是一个元素变量</h2>
function First(params) {
if(params.name==='李磊'){
return <h1>欢迎{params.name}</h1>
}
console.log(params);
return html
}
export default First
4.结果
案例2(简洁)
1.index.js引入子组件
import Second from './index2'
2.index.js
ReactDOM.render(
<Second></Second>,
document.getElementById('root')
);
3.index2.js
import React from 'react'
const Second = props =>{
return(
<ul>
<li>22222222</li>
</ul>
)
}
export default Second
4.结果
虚拟DOM
为了实现页面中dom的高效更新
浏览器引擎工作流程
创建dom tree-> 创建style rules -> 构建render tree -> 布局layout ->绘制painting
jsx
const html = <h2> 这是一个元素变量</h2>
上述标签语法既不是字符串也不是html,被称为jsx
案例3(时钟定时器写法)
setInterval(()=>{
ReactDOM.render(
// 通过属性传参,子组件通过params接收,相当于vue父子传参
<Tick date = {new Date()}></Tick>,
document.getElementById('root')
);
},1000)//index3.js
const Tick = (props)=>{
return(
<fieldset>
<legend>时间</legend>
<h1>北京时间:{props.date.toLocaleTimeString()}</h1>
</fieldset>
)
}
export default Tick
组合组件
案例4
//index.js
ReactDOM.render(
// 通过属性传参,子组件通过params接收,相当于vue父子传参
<Merge></Merge>,
document.getElementById('root')
);//index4.js
import React from 'react'
const Welcome = (props)=>{
return(
<h1>欢迎{props.name}</h1>
)
}
const Merge = ()=>{
return(
<fieldset>
<legend>组合组件</legend>
<Welcome name = '李伟'></Welcome>
<Welcome name = '谢伟'></Welcome>
</fieldset>
)
}
export default Merge
-
创建一个名称为
有状态组件
有状态组件相当于自己有经济来源,无状态组件没有经济来源
//index.js
ReactDOM.render(
// 通过属性传参,子组件通过params接收,相当于vue父子传参
<Index5></Index5> ,
document.getElementById('root')
);import React, { Component } from 'react';
import Tick from './index3';
class index5 extends Component {
constructor(){
super()
this.state={//1.定义局部状态,初始化状态
date:new Date()
}
}
tick(){
//2.更新状态this.setState()
this.setState({
date:new Date()
})
}
//3.挂载
componentDidMount(){//组件挂载,相当于vue中mounted
this.timer = setInterval(()=>{
this.tick()
},1000)
}
componentWillMount(){//卸载
clearInterval(this.timer)
}
//4.渲染
render() {
return (
<fieldset>
<legend>时间</legend>
<h1>北京时间:{this.state.date.toLocaleTimeString()}</h1>
</fieldset>
);
}
}
export default index5;
转换为类
-
创建一个名称扩展为
React.Component
的ES6 类 -
创建一个叫做
render()
的空方法 -
将函数体移动到
render()
方法中 -
在
render()
方法中,使用this.props
替换props
-
删除剩余的空函数声明
super作用
1.在子类使用this之前 必须调用 super()方法 获取this正确的指向 2.调用super相当于调用了父类的构造函数 3.使用super必须以调用函数的形式使用或者访问属性的方式使用它,可以使用super直接调用父类的动态方法
状态
与属性十分相似,但是状态是私有的,完全受控于当前组件。
不要直接更新状态
调用this.setState相当于调用了render方法
// Wrong
this.state.comment = 'Hello';
应当使用 setState()
:
// Correct
this.setState({comment: 'Hello'});
构造函数是唯一能够初始化 this.state
的地方。
状态更新可能是异步的
this.setState调用函数
例如,此代码可能无法更新计数器:
// 错误实例
this.setState({
counter: this.state.counter + this.props.increment,
});
要修复它,请使用第二种形式的 setState()
来接受一个函数而不是一个对象。 该函数将接收先前的状态作为第一个参数,将此次更新被应用时的props做为第二个参数:
// Correct
this.setState((prevState, props) => ({
//prevState得到上一个state
counter: prevState.counter + props.increment
}));
上方代码使用了箭头函数,但它也适用于常规函数:
// Correct
this.setState(function(prevState, props) {
return {
counter: prevState.counter + props.increment
};
});
状态更新合并
React 可以将多个setState()
调用合并成一个调用来提高性能。
当你调用 setState()
时,React 将你提供的对象合并到当前状态。
例如,你的状态可能包含一些独立的变量:
constructor(props) {
super(props);
this.state = {
posts: [],
comments: []
};
}
你可以调用 setState()
独立地更新它们:
componentDidMount() {
fetchPosts().then(response => {
this.setState({
posts: response.posts
});
});
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
}
这里的合并是浅合并,也就是说this.setState({comments})
完整保留了this.state.posts
,但完全替换了this.state.comments
。
总结:用心看,知识不多,今日掌握已足够