react基础知识

第一章 react简介

1.什么是react

用于构建用户界面的JavaScript库,是一个将数据渲染为HTML试图的开源JavaScript库

2.为什么选择使用react

1.原生JavaScript操作DOM繁琐、效率低

2.使用JavaScript直接操作DOM,浏览器会进行大量的重绘重排

3.原生JavaScript没有组件化编码方案,代码复用率低

3.react的特点

1.采用组件化模式、声明式编码,提高开发效率及组件复用率。

2.在React Native中可以使用React 语法进行移动端开发

3.使用虚拟DOM+优秀的Diffing算法,尽量减少与真实的DOM交互

第二章 React的基本使用

babel的作用 ES6转换ES5 JSX转换js

1.引入JS库进行使用(未使用脚手架的方式)

  <!--引入react核心库-->
<script type="text/javascript" src ="../js/react.development.js"></script>
<!--引入react-dom 用于支持react操作DOM-->
<script type="text/script" src="../js/react-dom.development.js"></script>
<!--引入babel 用于将JSX转换为JS-->
<script type="text/script" src="../js/babel.min.js"></script>

2.虚拟DOM

1.本质是Object类型的对象

2.虚拟DOM属性较少,真实DOM属性较多

3.虚拟DOM最终会被React转换为真实DOM渲染在页面上

3.JSX

1.react定义的一种类似于XML的JS扩展语法

2.本质是React.createElement(component,props,...children)方法的语法糖

3.作用:用来简化创建虚拟DOM

4.jsx语法规则:(1)定义虚拟DOM时,不要写引号

(2)标签中混入js 表达式时要用{}

(3)样式的类名指定要用ClassName

(4)内联style样式需要用{{}}

(5)只能有一个根标签,所有标签必须闭合。

(6)组件名首字母必须大写

4.数据绑定

1.对象数据不允许直接使用

2.Boolean,undefined,null在页面展示需要借助三元运算符

3.数组 会将数据的每一项拆分开

4.数据要存放在state中

5.修改数据需要使用setState,setState触发render再次执行,更新页面数据

6.在同步内循环内多次的setState会被合并成一次执行,在异步内setState不会被合并

7.setState是一个异步的方法,第一个参数是要修改的数据,第二个参数是数据修改成功,页面更新完成后的回调,类似vue中的nextTick

5.属性绑定

标签上的属性值是动态的,可以是变量可以是表达式。

6.指令

条件渲染:react没有v-if,但是可以借助三元表达式、或(||)运算符,与(&&)运算符,渲染函数实现条件渲染

列表渲染:react没有v-for,但是可以借助map方法

7.事件

1.react事件是合成事件 事件名称是原生js事件名变为小驼峰 事件的处理函数 直接作为class的属性 注意 函数内this的问题

2.react也有默认事件对象,事件对象和其他参数同时存在 事件对象会移动到最后

第三章 模块化与组件化

1.模块

向外提供特定功能的js程序,一般就是一个js文件

作用:复用js,简化js的编写,提高js运行效率。

2.模块化

当应用 js都以模块来编写的,这个应用就是一个模块化的应用

3.组件

用来实现局部功能效果的代码和资源的集合

作用:复用代码,简化项目编码,提高运行效率

4.组件化

当应用是以多组件的方式实现,这个应用就是组件化的应用

5.定义组件的两种方式

1.函数式组件(简单组件,无状态组件)

1.创建函数式组件
function Demo(){
console.log(this) 此处的this是undefined,因为babel编译后开启了严格模式
return <h2>我是函数式组件</h2>
}
2.渲染函数式组件
React.render(<Demo/>,document.getElementById('test'))

2.类式组件 (复杂组件,有状态组件)

1.创建类式组件
class MyComponent extends React.Component{
render(){  //render放在MyComponent原型对象上,供实例使用 
    return <h2>我是函数式组件</h2>
}
}
2.渲染类式组件
React.render(<MyComponent/>,document.getElementById('test'))

第四章 react的核心属性

1.state

(1)state是组件对象最重要的属性,值是对象(可以包含多个key-value的组合)

(2)组件被称为状态机,通过更新组件的state来更新对应的页面显示(重新渲染组件)

注意点

  1. 组件中render方法中的this为组件实例对象

  2. 组件自定义的方法中this为undefined 如何解决?(1)强制绑定this(2)箭头函数

  3. 状态数据,不能直接修改或更新

2.prop

1.使用prop-types检查props

React其实是为了构建大型应用程序而生, 在一个大型应用中,根本不知道别人使用你写的组件的时候会传入什么样的参数,有可能会造成应用程序运行不了,但是不报错。为了解决这个问题,React提供了一种机制,让写组件的人可以给组件的props设定参数检查,需要安装和使用prop-types:

npm i prop-types -S
import React, { Component } from 'react';
import PropTypes from 'prop-types'
​
// 如果需要验证子组件的属性的数据类型
// https://react.docschina.org/docs/typechecking-with-proptypes.html
// 自 React v15.5 起,React.PropTypes 已移入另一个包中。 cnpm i prop-types -S
// 在定义完组件以后,通过 组件.propTypes = { key: PropTypes.数据类型 } 验证属性的数据类型
// 如果某一个属性的值是必须要传递的属性, 通过 PropTypes.数据类型.isRequired 实现(如果设置了默认值,也算传递了属性)
// 如果某一个属性的值 既可以是 字符串,也可以是number,那么通过 PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]) 实现
// 如果既可以是 多类型,也是必传项,通过  PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]).isRequired 实现
// 如果需要指定一个自定义验证器。它在验证失败时应返回一个 Error 对象。
​
const Header = (props) => {
  return (
    <div>欢迎来到 { props.title } 的世界</div>
  )
}
Header.defaultProps = {
  title: 'React'
}
Header.propTypes = {
  // title: PropTypes.string
  title: PropTypes.string.isRequired // 代表该属性是必须传递的
}
function Content (props) {
  return (
    <div>
      { props.content }的核心库只关注于视图层
    </div>
  )
}
Content.defaultProps = {
  content: 'React.js'
}
Content.propTypes = {
  // content: PropTypes.number
  // content: PropTypes.string
  content: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]).isRequired
}
class Footer extends Component {
  // static defaultProps = { // 类组件,可以通过类的静态属性设置默认值
  //   name: 'React.js'
  // }
  render () {
    return (
      <div>
        学 { this.props.name } 实际上就是学习js
      </div>
    )
  }
}
Footer.defaultProps = {
  name: 'React'
}
Footer.propTypes = {
  // name: PropTypes.string
  name: function (props, propName, componentName) {
    console.log(props) // { name: 'React' }
    console.log(propName) // name
    console.log(componentName) // Footer
    // 如果需要指定一个自定义验证器。它在验证失败时应返回一个 Error 对象
    if (props[propName].length < 6) {
      return new Error(`传递的${propName}的长度必须大于等于6`)
    }
  }
}
class App extends Component {
  render() {
    return (
      <div>
        <Header ></Header>
        <Content ></Content>
        <Footer ></Footer>
      </div>
    );
  }
}
​
export default App;

prop-types提供的所有检查能力:

import PropTypes from 'prop-types';
​
MyComponent.propTypes = {
  // 你可以将属性声明为 JS 原生类型,默认情况下
  // 这些属性都是可选的。
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,
​
  // 任何可被渲染的元素(包括数字、字符串、元素或数组)
  // (或 Fragment) 也包含这些类型。
  optionalNode: PropTypes.node,
​
  // 一个 React 元素。
  optionalElement: PropTypes.element,
​
  // 一个 React 元素类型(即,MyComponent)。
  optionalElementType: PropTypes.elementType,
​
  // 你也可以声明 prop 为类的实例,这里使用
  // JS 的 instanceof 操作符。
  optionalMessage: PropTypes.instanceOf(Message),
​
  // 你可以让你的 prop 只能是特定的值,指定它为
  // 枚举类型。
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),
​
  // 一个对象可以是几种类型中的任意一个类型
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),
​
  // 可以指定一个数组由某一类型的元素组成
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
​
  // 可以指定一个对象由某一类型的值组成
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),
​
  // 可以指定一个对象由特定的类型值组成
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),
​
  // An object with warnings on extra properties
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),
​
  // 你可以在任何 PropTypes 属性后面加上 `isRequired` ,确保
  // 这个 prop 没有被提供时,会打印警告信息。
  requiredFunc: PropTypes.func.isRequired,
​
  // 任意类型的必需数据
  requiredAny: PropTypes.any.isRequired,
​
  // 你可以指定一个自定义验证器。它在验证失败时应返回一个 Error 对象。
  // 请不要使用 `console.warn` 或抛出异常,因为这在 `oneOfType` 中不会起作用。
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },
​
  // 你也可以提供一个自定义的 `arrayOf` 或 `objectOf` 验证器。
  // 它应该在验证失败时返回一个 Error 对象。
  // 验证器将验证数组或对象中的每个值。验证器的前两个参数
  // 第一个是数组或对象本身
  // 第二个是他们当前的键。
  customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
};
​

如果既要验证数据类型也要自定义验证器,只能将验证数据类型写到自定义验证器内。

import React, { Component } from 'react';
import PropTypes, { number } from 'prop-types'
​
const Header = (props) => {
  return (
    <div>欢迎来到 { props.title } 的世界</div>
  )
}
Header.defaultProps = {
  title: 'React'
}
Header.propTypes = {
  // title: PropTypes.string
  title: PropTypes.string.isRequired // 代表该属性是必须传递的
}
function Content (props) {
  return (
    <div>
      { props.content }的核心库只关注于视图层
    </div>
  )
}
Content.defaultProps = {
  content: 'React.js'
}
Content.propTypes = {
  // content: PropTypes.number
  // content: PropTypes.string
  content: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]).isRequired
}
class Footer extends Component {
  // static defaultProps = { // 类组件,可以通过类的静态属性设置默认值
  //   name: 'React.js'
  // }
  render () {
    return (
      <div>
        学 { this.props.name } 实际上就是学习js
      </div>
    )
  }
}
Footer.defaultProps = {
  name: 'React'
}
Footer.propTypes = {
  // name: PropTypes.string
  name: function (props, propName, componentName) {
    console.log(props) // { name: 'React' }
    console.log(propName) // name
    console.log(componentName) // Footer
    if (typeof props[propName] !== 'number') { // 验证数据类型
      return new Error('请传递number类型的数据,现在是' + typeof props[propName] + '类型')
    }
    // 如果需要指定一个自定义验证器。它在验证失败时应返回一个 Error 对象
    if (props[propName].length < 6) {
      return new Error(`传递的${propName}的长度必须大于等于6`)
    }
  }
}
class App extends Component {
  render() {
    return (
      <div>
        <Header ></Header>
        <Content ></Content>
        <Footer ></Footer>
      </div>
    );
  }
}
​
export default App;

复习:判断是否是数组的方法。

其实React完全可以拥抱TypeScript来实现更强大的类型验证,包括但不限于属性的验证,选择TS后,将不需要使用PropTypes来进行验证。

函数式组件也能使用props,原因在于函数式组件可以接收参数。

2.基本使用

  • 内部读取某个属性值

    this.props.name
  • 对props中的属性值进行类型限制和必要性限制

    使用prop-types库进行限制

    Person.propTypes = {
    name:PropTypes.string.isRequired,
    age:PropTypes.number
    }
  • 扩展属性:将对象的所有属性通过props传递

    <Person {...person}/>
  • 默认属性值

    Person.defaultProps = {
    age:18,
    sex:'男'
    }
  • 组件类的构造函数

    constructor(props){
    super(props)
    console.log(props)//打印所有属性
    }
    

3.refs

Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素。

何时使用 Refs

  • 管理焦点,文本选择或媒体播放。

  • 触发强制动画。

  • 集成第三方 DOM 库。

    创建 Refs

    Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们。

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.myRef = React.createRef();  }
      render() {
        return <div ref={this.myRef} />;  }
    }

    访问 Refs

    当 ref 被传递给 render 中的元素时,对该节点的引用可以在 ref 的 current 属性中被访问。

    const node = this.myRef.current;

    ref 的值根据节点的类型而有所不同:

    • ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。

    • ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。

    • 你不能在函数组件上使用 ref 属性,因为他们没有实例。

    以下例子说明了这些差异。

    为 DOM 元素添加 ref

    以下代码使用 ref 去存储 DOM 节点的引用:

    class CustomTextInput extends React.Component {
      constructor(props) {
        super(props);
        // 创建一个 ref 来存储 textInput 的 DOM 元素
        this.textInput = React.createRef();    this.focusTextInput = this.focusTextInput.bind(this);
      }
    ​
      focusTextInput() {
        // 直接使用原生 API 使 text 输入框获得焦点
        // 注意:我们通过 "current" 来访问 DOM 节点
        this.textInput.current.focus();  }
    ​
      render() {
        // 告诉 React 我们想把 <input> ref 关联到
        // 构造器里创建的 `textInput` 上
        return (
          <div>
            <input
              type="text"
              ref={this.textInput} />        <input
              type="button"
              value="Focus the text input"
              onClick={this.focusTextInput}
            />
          </div>
        );
      }
    }

    React 会在组件挂载时给 current 属性传入 DOM 元素,并在组件卸载时传入 null 值。ref 会在 componentDidMountcomponentDidUpdate 生命周期钩子触发前更新。

    为 class 组件添加 Ref

    如果我们想包装上面的 CustomTextInput,来模拟它挂载之后立即被点击的操作,我们可以使用 ref 来获取这个自定义的 input 组件并手动调用它的 focusTextInput 方法:

    class AutoFocusTextInput extends React.Component {
      constructor(props) {
        super(props);
        this.textInput = React.createRef();  }
    ​
      componentDidMount() {
        this.textInput.current.focusTextInput();  }
    ​
      render() {
        return (
          <CustomTextInput ref={this.textInput} />    );
      }
    }

    请注意,这仅在 CustomTextInput 声明为 class 时才有效:

    class CustomTextInput extends React.Component {  // ...
    }

    Refs 与函数组件

    默认情况下,你不能在函数组件上使用 ref 属性,因为它们没有实例:

    function MyFunctionComponent() {  return <input />;
    }
    ​
    class Parent extends React.Component {
      constructor(props) {
        super(props);
        this.textInput = React.createRef();  }
      render() {
        // This will *not* work!
        return (
          <MyFunctionComponent ref={this.textInput} />    );
      }
    }

    如果要在函数组件中使用 ref,你可以使用 forwardRef(可与 useImperativeHandle 结合使用),或者可以将该组件转化为 class 组件。

    不管怎样,你可以在函数组件内部使用 ref 属性,只要它指向一个 DOM 元素或 class 组件:

    function CustomTextInput(props) {
      // 这里必须声明 textInput,这样 ref 才可以引用它  const textInput = useRef(null);
      function handleClick() {
        textInput.current.focus();  }
    ​
      return (
        <div>
          <input
            type="text"
            ref={textInput} />      <input
            type="button"
            value="Focus the text input"
            onClick={handleClick}
          />
        </div>
      );
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zwq8023520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值