/*
类组件:
*/
// 创建类组件
class Hello extends React.Component {
render() {
return (
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
2.3 抽离为独立 JS 文件
-
思考:项目中组件多了之后,该如何组织这些组件?
-
选择一:将所有的组件放在同一个JS文件中
-
选择二:将每个组件放到单独的JS文件中
-
组件作为一个独立的个体,一般都会放到一个单独的JS文件中
步骤及示例代码演示如下:
-
创建Hello.js
-
在 Hello.js 中导入React
-
创建组件(函数 或 类)
-
在 Hello.js 中导出该组件
-
在 index.js 中导入 Hello 组件
-
渲染组件
完整代码演示如下:
// Hello.js
import React from ‘react’
// 创建组件
class Hello extends React.Component {
render() {
return (
)
}
}
// 导出组件
export default Hello
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
抽离组件到独立的JS文件中
*/
// 导入Hello组件
import Hello from ‘./Hello’
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
(3)React 事件处理
3.1 事件绑定
-
React事件绑定语法与DOM事件语法相似
-
语法:on+事件名称={事件处理程序},比如 onClick = function(){}
-
注意:React事件采用驼峰命名法,比如:onMouseEnter、onFocus
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
React事件处理
*/
class App extends React.Component {
// 事件处理程序
handleClick() {
console.log(‘单击事件触发了’)
}
render() {
return (
点我,点我
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
React事件处理
*/
// 通过函数组件绑定事件:
function App() {
// 事件处理程序
function handleClick() {
console.log(‘函数组件中的事件绑定,事件触发了’)
}
return (
点我
)
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
3.2 事件对象
-
可以通过事件处理函数的参数获取到事件对象;
-
React中的事件对象叫做:合成事件;
-
合成事件:兼容所有浏览器,无需担心跨浏览器兼容问题;
-
除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括
stopPropagation()
和preventDefault()
; -
如果你想获取到原生事件对象,可以通过
nativeEvent
属性来进行获取;
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
React事件对象
*/
class App extends React.Component {
handleClick(e) {
// 阻止浏览器的默认行为
e.preventDefault()
console.log(‘a标签的单击事件触发了’)
}
render() {
return (
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
(4)有状态组件和无状态组件
-
函数组件又叫做 无状态组件,类组件又叫做 有状态组件;
-
状态(state) 即数据;
-
函数组件没有自己的状态,只负责数据展示;
-
类组件有自己的状态,负责更新UI,让页面动起来;
比如计数器案例中,点击按钮让数值加 1 。0 和 1 就是不同时刻的状态,而由 0 变为 1 就表示状态发生了变化。状态变化后,UI 也要相应的更新。React 中想要实现该功能,就要使用有状态组件来完成。
(5)组件中的 state 和 setState()
5.1 state的基本使用
-
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用;
-
state的值是对象,表示一个组件中可以有多个数据;
-
通过
this.state
来获取状态;
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
state的基本使用
*/
class App extends React.Component {
/* constructor() {
super()
// 初始化state
this.state = {
count: 0
}
} */
// 简化语法初始化state(推荐)
state = {
count: 10
}
render() {
return (
计数器:{this.state.count}
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
5.2 setState()修改状态
-
状态是可变的;
-
语法:this.setState({要修改的数据});
-
注意:不要直接修改state中的值,这是错误的;
-
setState() 作用:1.修改 state 2.更新UI;
-
思想:数据驱动视图;
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
state的基本使用
*/
class App extends React.Component {
state = {
count: 0
}
render() {
return (
计数器:{this.state.count}
<button onClick={() => {
this.setState({
count: this.state.count + 1
})
// 错误!!!
// this.state.count += 1
}}>+1
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
5.3 从 JSX 中抽离事件处理程序
-
JSX 中掺杂过多 JS 逻辑代码,会显得非常混乱;
-
推荐:将逻辑抽离到单独的方法中,保证 JSX 结构清晰;
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
从JSX中抽离事件处理程序
*/
class App extends React.Component {
state = {
count: 0
}
// 事件处理程序
onIncrement() {
console.log(‘事件处理程序中的this:’, this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
计数器:{this.state.count}
+1
{/* <button onClick={() => {
this.setState({
count: this.state.count + 1
})
}}>+1 */}
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
- 原因:事件处理程序中 this 的值为
undefined
,在JSX中我们写的事件处理函数可以找到this,原因在于在JSX中我们利用箭头函数,箭头函数是不会绑定this,所以会向外一层去寻找,外层是render方法,在render方法里面的this刚好指向的是当前实例对象;
(6)事件绑定 this 指向
6.1 箭头函数
-
利用箭头函数自身不绑定this的特点
-
render() 方法中的 this 为组件实例,可以获取到 setState()
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
从JSX中抽离事件处理程序
*/
class App extends React.Component {
state = {
count: 0
}
// 事件处理程序
onIncrement() {
console.log(‘事件处理程序中的this:’, this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
计数器:{this.state.count}
<button onClick={() => this.onIncrement()}>+1
{/* +1 */}
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
6.2 Function.prototype.bind()
利用原型bind方法是可以更改函数里面this的指向的,所以我们可以在构造中调用bind方法,然后把返回的值赋值给我们的函数即可。
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
从JSX中抽离事件处理程序
*/
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
// 通过bind方法改变了当前函数中this的指向
this.onIncrement = this.onIncrement.bind(this)
}
// 事件处理程序
onIncrement() {
console.log(‘事件处理程序中的this:’, this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
计数器:{this.state.count}
+1
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
6.3 class 的实例方法
-
利用箭头函数形式的class实例方法
-
注意:该语法是实验性语法,但是,由于babel的存在可以使用
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
从JSX中抽离事件处理程序
*/
class App extends React.Component {
state = {
count: 0
}
// 事件处理程序
onIncrement = () => {
console.log(‘事件处理程序中的this:’, this)
this.setState({
count: this.state.count + 1
})
}
render() {
return (
计数器:{this.state.count}
+1
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
(7)表单处理
7.1 受控组件
-
HTML中的表单元素是可输入的,也就是有自己的可变状态;
-
而React中可变状态通常保存在state中,并且只能通过
setState()
方法来修改; -
React讲state与表单元素值value绑定在一起,由state的值来控制表单元素的值;
-
受控组件:值受到react控制的表单元素;
步骤及示例代码演示如下:
-
在 state 中添加一个状态,作为表单元素的value值(控制表单元素值的来源);
-
给表单元素绑定 change 事件,将 表单元素的值 设置为 state 的值(控制表单元素值的变化);
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
受控组件:其值受到React控制的表单元素
操作文本框的值:
*/
class App extends React.Component {
state = {
txt: ‘’
}
handleChange = e => {
this.setState({
txt: e.target.value
})
}
render() {
return (
/* 把state的值设置给输入框的value,绑定change事件,这样用户在输入内容的时候
调用相应函数,在函数里面把当前设置的值赋值给state,从而达到数据的统一 */
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
7.1.1 受控组件示例
文本框、富文本框、下拉框、复选框
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
受控组件示例
*/
class App extends React.Component {
state = {
txt: ‘’,
content: ‘’,
city: ‘bj’,
isChecked: false
}
handleChange = e => {
this.setState({
txt: e.target.value
})
}
// 处理富文本框的变化
handleContent = e => {
this.setState({
content: e.target.value
})
}
// 处理下拉框的变化
handleCity = e => {
this.setState({
city: e.target.value
})
}
// 处理复选框的变化
handleChecked = e => {
this.setState({
isChecked: e.target.checked
})
}
render() {
return (
{/* 文本框 */}
{/* 富文本框 */}
{/* 下拉框 */}
上海 北京 广州{/* 复选框 */}
)
}
}
// 渲染组件
ReactDOM.render(, document.getElementById(‘root’))
7.1.2 多表单元素优化
多表单元素优化:
-
问题:每个表单元素都有一个单独的事件处理程序处理太繁琐;
-
优化:使用一个事件处理程序同时处理多个表单元素;
多表单元素优化步骤:
-
给表单元素添加name属性,名称与 state 相同;
-
根据表单元素类型获取对应值;
-
在 change 事件处理程序中通过 [name] 来修改对应的state;
完整代码演示如下:
import React from ‘react’
import ReactDOM from ‘react-dom’
/*
受控组件示例
*/
class App extends React.Component {
ES6
-
列举常用的ES6特性:
-
箭头函数需要注意哪些地方?
-
let、const、var
-
拓展:var方式定义的变量有什么样的bug?
-
Set数据结构
-
拓展:数组去重的方法
-
箭头函数this的指向。
-
手写ES6 class继承。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
微信小程序
-
简单描述一下微信小程序的相关文件类型?
-
你是怎么封装微信小程序的数据请求?
-
有哪些参数传值的方法?
-
你使用过哪些方法,来提高微信小程序的应用速度?
-
小程序和原生App哪个好?
-
简述微信小程序原理?
-
分析微信小程序的优劣势
-
怎么解决小程序的异步请求问题?
其他知识点面试
-
webpack的原理
-
webpack的loader和plugin的区别?
-
怎么使用webpack对项目进行优化?
-
防抖、节流
-
浏览器的缓存机制
-
描述一下二叉树, 并说明二叉树的几种遍历方式?
-
项目类问题
-
笔试编程题:
最后
技术栈比较搭,基本用过的东西都是一模一样的。快手终面喜欢问智力题,校招也是终面问智力题,大家要准备一下一些经典智力题。如果排列组合、概率论这些基础忘了,建议回去补一下。