文章目录
b站课程链接跳转
ps: written by Winter-prince
学习前端React做的笔记,供以后复习使用。关键代码基本上都有截图和文字说明,有些部分可能由于内容比较简单没有记录,点击上方课程链接即可跳转前往课程查看详情,关于React的笔记一共有5篇博客,如果需要查看完整内容的请前往专栏查看
我的github:Winter-prince
只关注页面的呈现,HTML视图
Facebook开发
- JS DOM操作UI效率低,浏览器的负担重
- 直接操作DOM,大量的重绘重排
- 原生JS没有组件化
P1-20
React的特点
- 采用组件化模式、声明式编码,提高开发效率及组件复用率。
- 在React Native中可以使用React语法进行移动端开发。
- 使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互。
判断this的指向、class(类)、ES6语法规范、npm包管理器、原型、原型链、数组常用方法、模块化
初学,在浏览器中开发,在html中引入js
babel.min.js
react.development.js
react-dom.development.js
蓝色的要在红色的之前引入
浏览器babel.js现场翻译,可能会导致白屏
render替换
使用原生js实现创建虚拟DOM:
<script type="text/javascript">
//1.创建虚拟DOM
const VDOM = React.createElement(
"h1",
{ id: "title" },
React.createElement("span", {}, "Hello,React")
);
//2.渲染虚拟DOM到页面
ReactDoM.render(VDOM, document.getElementById("test"));
</script>
js
<script type="text/babel" > {/*此处一定要写babel */}
{/*1.创建虚拟DOM*/}
{/* 此处一定不要写引号,因为不是字符串*/}
const VDOM = (
<h1 id="title">
<span>Hello, React</span>
</h1>
{/*2.渲染虚拟DOM到页面*/}
ReactDOM.render(VDOM, document.getElementById('test'))
</script>
babel最终会将jsx的语法转换为原生js的语法
P4
P5 jsx语法核心规则
jsx语法核心规则
jsx语法规则:
1.定义虚拟DOM时,不要写引号。
2.标签中混入JS表达式时要用{}。
3.样式的类名指定不要用class,要用className.
4.内联样式,要用style={{key:value}}的形式去写。
5.只有一个根标签
6.标签必须闭合
7.标签首字母
(1).若小写字母开头,则将改标签转为html中同名元素,若html中 无该标签对应的同名元素,则报错。
(2).若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。
P6 jsx练习
一定注意区分:【js语句(代码)】与【js表达式】
1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方
下面这些都是表达式:
(1). a
(2). a+b
(3). demo(1)
(4). arr.map()
(5). function test () {}
2.语句(代码):
下面这些都是语句(代码):
(1).if(){}
(2). for(){}
(3). switch( ){case:xxxx}
数据模拟
//模拟一些数据
const data = ["Angular", "React", "Vue"];
//1.创建虚拟DOM
const VDOM = (
<div>
<h1>前端js框架列表</h1>
<ul>
{data.map((item, index) => {
return <li key={index}>{item}</li>;
})}
</ul>
</div>
);
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM, document.getElementById("test"));
P7 模块化
理解
P8
P9 函数式组件
按住shift+点击刷新就是强制刷新,清除浏览器的缓存
P10 类复习
call apply bind 更改this指向
// bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
var obj = {
name: "wangcai",
age: 18,
fn: function () {
console.log(this);
},
};
var person = { name: "张三" };
var res = obj.fn.bind(person);
res(); //{name: '张三'}
console.log(person); //{name: '张三'}
继承中写了构造器必须调用super
super必须放在所有this之前
原型链
P11 类式组件
实现render方法
P12 state
有state->复杂组件
无state->简单组件
组件的数据放在状态里,状态驱动页面
组件实例的三大属性1.state2.props3.refs
P13 初始化state
使用解构赋值
P14 react事件绑定
原生js事件绑定
<button id="btn1"> 按钮1< /button>
<button id="btn2">按钮2< /button>
<button onclick="demo()"> 按钮3< /button>
<script type="text/javascript" >
const btn1 = document.getElementById("btn1");
btn1.addEventListener("click", () => {
alert("按钮1被点击了");
});
const btn2 = document.getElementById("btn2");
btn2.onclick = () => {
alert("按钮2被点击了");
};
function demo() {
alert("按钮3被点击了");
}
</script>
尽量避免写document
react绑定事件(外部函数)
//1.创建组件
class Weather extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = { isHot: false };
}
render() {
//读取状态
const { isHot } = this.state;
return <h1 onClick={demo}>今天天气很{isHot ? "炎热" : " 凉爽"}</h1>;
}
}
//2.渲染组件到页面
ReactDOM.render(<Weather />, document.getElementById("test"));
function demo() {
console.log("标题被点击了");
}
P15 类中方法this的指向
this丢失问题
1.babel使用严格模式,所以是undefined
2.类方法的直接调用
P16 解决this指向问题
可以使用bind方法从原型上获取(属性/方法)生成一个新的挂到实例上。
//1.创建组件
class Weather extends React.Component {
constructor(props) {
super(props);
//初始化状态.
this.state = { isHot: false };
//解决changeWeathEr中this指向问题
this.changeweather = this.changeWeather.bind(this);
}
render() {
//读取状态
const { isHot } = this.state;
return (
<h1 onClick={this.changeWeather}>今天天气很{isHot ? "炎热" : " 凉爽"}</h1>
);
}
changeWeather() {
//changeweather放在哪里?一Weather的原型对象 上,供实例使用
//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
console.log(this);
}
}
//2.渲染组件到页面
ReactDOM.render(<Weather />, document.getElementById("test"));
对应
constructor(props) {
super(props);
//初始化状态
this.state = { isHot: false };
this.nice = this.test.blind(this);
}
render() {
//读取状态</this>
const { isHot } = this.testa;
return <h1 onClick={this.nice}>今天天气很{isHot ? " 炎热" : " 凉爽"}</h1>;
}
test() {
//changeWeather放在哪里?- Weather的 原型对象上,供实例使用
//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式,所以changelWeather中 的this为undefined
console.log(this);
}
P17 setState
状态不可直接更改,要借助内置API——setState
changeWeather(){
//changeWeather放在哪里?一Weather的原型对象 上,供实例使用
//由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
//类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined
//获取原来的isHot值
const isHot = this.state.isHot
//严重注意:状态必须通过setState进行更新
this.setState({isHot : !isHot})
//严重注意:状态(state)不可 直接更改,下面这行就是直接更改! ! !
// this.state.isHot = !isHot //这是错误的写法
}
且使用setState是一种合并,对于同名的会进行修改,不同名的不动
构造器执行1次
render调用1+n次
P18 精简state
//1.创建组件
class Weather extends React.Component{
state = {isHot:false ,wind:'微风'}
render(){
const {isHot,wind} = this.state
return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'}, {wind}</h1>
changeWeather = ()=>{
const isHot = this.state.isHot
this.setState({isHot:!isHot})
}
}
}
//2.渲染组件到页面
ReactDOM.render( <Weather/> , document.getElementById('test'))
箭头函数自己是没有this的,如果内部出现了this,那么将会从箭头函数的外部寻找this
P19 state总结
组件=状态机,根据state更改显示页面
P20 props
//创建组件
class Person extends React.Component {
render() {
console.log(this);
const { name, age, sex } = this.props;
return (
<ul>
<li>姓名: {name}</li>
<li>性别: {sex}</li>
<li>年龄: {age}</li>
</ul>
);
}
}
//渲染组件到页面
ReactDOM.render(
<Person name="jerry" age="19" sex="男" />,
document.getElementById("test1")
);
ReactDOM.render(
<Person name="tom" age="18" sex="女" />,
document.getElementById("test2")
);
ReactDOM.render(
<Person name=" 老刘" age="30" sex=" 女" />,
document.getElementById("test3")
);