用于构建用户界面的javascript库
库:提供一些可以使用方法框架:提供一套开发规则,规范,根据规则去编程创建组件的类型 组件是react开发中最重要的一点,我们一般吧组件分为3种类型(容器组件,展示组件,业务组件)
容器组件: 路由对应的组件,用于将展示组件和业务组件组合成一个完整的页面,管理页面中需要的数据,和服务端发生交互展示组件:纯粹的展示操作,接收数据展示,复用性强,一般使用函数创建的方式创建组件业务组件:有独立的逻辑操作,涉及到服务端交互的组件,复用性弱,一般只是为了将页面中的一个功能点单独拆封出来2,class类的方式:使用es6的class创建的组件,需要继承(Component, PureComponent,其他组件),有自己的状态,生命周期
import React, {Component, PureComponent} from 'react' class ComponentName extends Component { render () { return <div></div> } } class ComponentName extends PureComponent { render () { return <div></div> } }通信指的是两个或者多个组件直接的数据传递,根据组件的树的嵌套关系一般有个这么几个场景(父子,子父,同级,跨级)
父子:子组件使用父组件的数据 可以使用属性进行传递,在组件内通过props接收子父:父组件使用子组件的数据 可以使用属性传递一个函数,在组件内通过props接收并且执行这个函数,传递父组件需要的数据同级:两个同级关系的组件相互传递数据 1,可以自定义一个全局的自定义事件管理器(发布订阅) bus,一个组件定义事件,另一个组件执行事件2,redux3,状态提升:吧俩组件需要用到的数据提升到他们共同的父组件 跨级:context api夸组件传参数 const ThemeContext = React.createContext(); <ThemeContext.Provider value={需要传递的数据}> 内部任意位置 <ThemeContext.Consumer> {(value) => { console.log(value) // 接收到的数据 }} </ThemeContext.Consumer> </ThemeContext.Provider>在react实现数据双向绑定的方案,利用的数据驱动,和onChange监听
<input value={this.state.val} onChange={(e) => this.setState({val: e.target.value})}>就是将元素进行了存储,利用了ref进行元素的获取,保持了元素的dom
input = React.createRef(); <input ref={input}>受控组件和非受控组件的区别就在于一个操作状态,一个操作元素
组件和组件直接有嵌套关系,和html中 元素嵌套一样,只不过,我门组件嵌套需要在组件内部接收(this.props.children)
<Tab> <Tab.Item title="标签一">内容内容内容内容内容</Tab.Item> <Tab.Item title="标签二">内容内容内容内容内容</Tab.Item> <Tab.Item title="标签三">内容内容内容内容内容</Tab.Item> <Tab.Item title="标签四">内容内容内容内容内容</Tab.Item> </Tab>在react事件绑定在jsx元素上,是合成事件,规则是onClick这样的命名 合成事件的优点:兼容,优化 缺点:this不会自动的执行当前组件实例,也不是当前绑定事件的dom。我们需要手动绑定this,或者使用箭头函数
jsx是react中用来创建虚拟dom的语法,是一个语法糖,最终会被编译成React.createElement()函数的调用,返回值是一个对象(虚拟dom)
jsx和html的区别 1,在jsx中我们可以使用{}输出js表达式,用来给jsx提供逻辑 2,个别属性的区别className htmlFor, … 3,安全
属性和状态是组件的数据来源
在组件元素上通过属性进行传递,在组件内部通过props接收,我们可以使用静态属性 propsDefault设置props的默认值,使用propTypes设置props的类型
props不允许被改变
class ComponentName extends Component { // 默认值 static defaultProps = { propsName: [] } // 类型 static propTypes: { propsName: proptypes.string } }class创建的组件是通过继承得到的props属性,函数组件是通过函数参数得到的props
组件内部的数据,使用this.state设置, this.state.xxx获取, this.setState({xxx: newValue})改变
setState是react中用来改变state的方法,改变并且能够使我们的组件重新渲染,是一个异步函数
语法: this.setState({ updateState: newValue }, () => { console.log('改变完成的回调') })在特点场景下,连续多个`setState会合并成一个setState的执行(事件处理函数,生命周期中)直接调用 其他场景都不会合并,调用setState就会执行
setState的第二个参数,会在render之后执行
setState之后生命周期的变化 shouldComponentUpdate 通过返回true和false来决定后面生命周期的执行 componentWillUpate render 子组的重新渲染 componentDidUpate
高阶组件并不是react的概念,他就是我们js中的高阶函数,只不过在react中高阶组件是用来扩展组件的
1,属性扩展: 我们给组件扩展一些公用的属性 2,反向继承: 通过继承,我们需要包装的组件,可以操作原组件的生命周期,或者其他函数,或者状态 super 3,组件组合: 可以通过高阶组件组合多个组件
使用方法就是:一个函数接收一个组件,返回一个新组件 优点:可以抽离更多的公共逻辑 缺点:通过ref就获取不到原组件的实例了,需要手动转发ref
// 属性代理 const HocComponent = (WrappedComponent) => { return class extends Component { render () { const extendProps ={ aa: 'aaa', bb: 'bbbb' } return <WrappedComponent {...this.props} {...extendProps}> } } } // 反向继承 const HocComponent = (WrappedComponent) => { return class extends WrappedComponent { componentDidMount () { super.componentDidMount() } render () { return super.render() } } } const HocComponent = (WrappedComponent) => { return class extends Component { render () { return ( <div> <Filter /> <WrappedComponent {...this.props} {...extendProps}> <Page /> </div> ) } } }1,循环加key: key值为数据的id,索引会通过crud进行改变,而id是固定的 2,生命周期的优化:shouldComponentUpdate 做数据的前后对比,进行执行优化, 简单的方式可以使用PureComponent(浅对比) 3,虚拟化长列表