1.react特点
①声明式编码
②组件化编码
③React Native 编写原生应用
④高效(优秀的diffing算法)
⑤用于动态构建用户界面的js库(只关注视图)
2.React高效的原因
①使用虚拟DOM,不总是直接操作页面真实的DOM
②Diffing算法,最小化页面重绘
3.jsx
①全称:javaScript XML,react定义的一种类似于XML的js扩展语法:js+XML,
最终解析为js
②作用:用来简化创建虚拟DOM
jsx语法规则:
①定义虚拟DOM时,不要写引号。
②标签中混入js表达式时要用{}
③样式的类名指定使用className
④内联样式,要用style={{key:value}}的形式去写。
⑤只有一个根标签,并且标签必须闭合
⑥
(1)若小写字母开头,则将改标签转为html中同名元素,若html中无该标签对应的同名元素,则保持。
(2)若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。
4.函数组件和类组件的基本区别
类组件有生命周期,函数组件没有
类组件需要继承 Class,函数组件不需要
类组件可以获取实例化的 this,并且基于 this 做各种操作,函数组件不行
类组件内部可以定义并维护 state, 函数组件为无状态组件(可以通过hooks实现)
函数组件相比较类组件,优点是更轻量与灵活,便于逻辑的拆分复用。
类组件使用:
- import React, { Component } from 'react'
- // 定义类组件
- export default class ClassHanshu extends Component {
- // 1.类中的构造器不是必须要写的,要对实例进行一些初始化的操作,如添加指定属性时才写
- // 2.类中所定义的方法,都放在了类的原型对象上,供实例使用
- // 3.如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须调用的
- constructor() {
-
- super()
- this.state = {
- flag: true,
- count: 0
- }
- }
- addCount() {
- //constructor中的state不能直接修改
- this.setState({
- count: this.state.count += 1
- })
- }
- changeText() {
- this.setState({
- flag: !this.state.flag
- })
- }
- render() {
- // 解构
- const { flag, count } = this.state
- console.log(flag);
- return (
- <div>CountClass
- {/* 此处的this.state就不用再写了 */}
- <p onClick={() => this.changeText()}>ad{flag ? "a" : "d"}p>
- <button onClick={() => this.addCount()}>{count}button>
- div>
- )
- }
- }
类组件中的state属性:
1.state是组件对象最重要的属性,值是对象
2.组件被称为“状态机”,通过更新组件的state来更新对应的页面显示
注意:
1.组件中render方法中的this为组件的实例对象
2.当组件自定义方法中的this为undefined时,可以通过函数对象的bind()强制绑定this或箭头函数
3.状态数据,不能直接修改或更新
5.ref的三种使用方法
- import React, { Component } from 'react'
-
- export default class ClassHanshu extends Component {
- constructor() {
- super()
- }
- showData() {
- // js写法
- // const btn = document.getElementById("btn")
- // console.log(btn.value);
- // console.log(this.refs.value);拿不到数据
- // 解构 字符串ref用法
- // const { btn } = this.refs
- // console.log(btn.value);
- }
- showData1() {
- // 回调ref
- const { btn } = this
- alert(btn.value)
- }
-
- render() {
- return (
- <div>
- {/* 1.字符串ref的使用 */}
- {/* <input id="btn" type="text" placeholder='点击按钮提示数据' />
- <button onClick={() => this.showData()}>点击打印数据button> */}
- {/* <input ref="btn" type="text" placeholder='点击按钮提示数据' />
- <button onClick={() => this.showData()}>点击打印数据button> */}
-
- {/* 2.回调ref */}
- <input ref={c => this.btn = c} type="text" placeholder='点击按钮提示数据' />
- <button onClick={() => this.showData1()}>点击打印数据button>
- div>
- )
- }
- }
- import React, { Component } from 'react'
-
- export default class ClassHanshu extends Component {
- constructor() {
- super()
- // 3.createRef API方式
- // React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点
- // 该容器是专人专用的,所以不同的元素使用都要在constructor调用
- this.myRef = React.createRef()
- this.myRef1 = React.createRef()
- }
-
- showData() {
- alert(this.myRef.current.value)
- }
- showData1() {
- alert(this.myRef1.current.value)
- }
- render() {
- return (
- <div>
- <input ref={this.myRef} type="text" placeholder='点击按钮提示数据' />
- <button onClick={() => this.showData()}>点击打印数据button>
- <input ref={this.myRef1} type="text" placeholder='点击按钮提示数据' />
- <button onClick={() => this.showData1()}>点击打印数据button>
- div>
- )
- }
- }
6.表单之非受控组件和受控组件
- import React, { Component } from 'react'
-
- export default class ClassHanshu extends Component {
- constructor() {
- super()
- }
- // 非受控组件
- handleSubmit = (event) => {
- // 阻止默认事件
- event.preventDefault();
- // 现用现取为非受控组件
- const { username, password } = this
- alert(`username的值是:${username.value},password的值是:${password.value}`)
- }
- render() {
- return (
- <div>
- <form onSubmit={this.handleSubmit}>
- 用户名: <input type="text" name="username" ref={c => this.username = c} />
- 密码: <input type="password" name="password" ref={c => this.password = c} />
- <button>登录button>
- form>
- div>
- )
- }
- }
- import React, { Component } from 'react'
-
- export default class ClassHanshu extends Component {
- constructor() {
- super()
- this.state = {
- username: "",
- password: ""
- }
- }
- // 受控组件,输入框输入的值可以实时获取到,建议使用受控组件可以省略掉ref(官网建议请勿过度使用ref)
- // 表单提交的回调
- handleSubmit = (event) => {
- // 阻止默认事件
- event.preventDefault();
- const { username, password } = this.state
- console.log(`username的值是:${username},password的值是:${password}`)
- }
- saveUsername = (event) => {
- this.setState({
- username: event.target.value
- })
- }
- savePassword = (event) => {
- this.setState({
- password: event.target.value
- })
- }
- render() {
- return (
- <div>
- <form onSubmit={this.handleSubmit}>
- 用户名: <input type="text" name="username" onChange={this.saveUsername} />
- 密码: <input type="password" name="password" onChange={this.savePassword} />
- <button>登录button>
- form>
- div>
- )
- }
- }
7.高阶函数和函数柯里化,解决受控组件代码冗余问题
- import React, { Component } from 'react'
-
- export default class ClassHanshu extends Component {
- constructor() {
- super()
- this.state = {
- username: "",
- password: ""
- }
- }
-
- handleSubmit = (event) => {
- // 阻止默认事件
- event.preventDefault();
- const { username, password } = this.state
- console.log(`username的值是:${username},password的值是:${password}`)
- }
- // 通过高阶函数解决受控组件代码冗余的问题
- // 高阶组件 1.若A函数,接受的参数是一个函数,那么A就可以称为高阶函数
- // 2.若A函数,调用的返回值依然是一个函数,那么A就可以称为高阶函数
- // 常见高阶函数:promise setTimeout arr.map()等
- // 函数柯里化:通过函数调用回继续返函数的方式,实现多次接收参数最后统一处理的函数编码形式
-
- // 以下的saveForm就是高阶函数,里面返回的是箭头函数(柯里化)
- saveForm = (dataType) => {
- return (event) => {
- this.setState({
- [dataType]: event.target.value
- })
- }
- }
- render() {
- return (
- <div>
- <form onSubmit={this.handleSubmit}>
- 用户名: <input type="text" name="username" onChange={this.saveForm("username")} />
- 密码: <input type="password" name="password" onChange={this.saveForm("password")} />
- <button>登录button>
- form>
- div>
- )
- }
- }