react基础

React facebook团队开发

1.用来构建UI的 JavaScript库
2.React 不是一个 MVC 框架,仅仅是视图(V)层的库

特点

1 使用 JSX语法 创建组件,实现组件化开发,为函数式的 UI 编程方式打开了大门
2 性能高的让人称赞:通过 diff算法 和 虚拟DOM 实现视图的高效更新

React中的核心概念

1 虚拟DOM(Virtual DOM)
2 Diff算法(虚拟DOM的加速器,提升React性能的法宝)

JSX 的基本使用

JSX= js+html react 是js库
JSX 是 JavaScript 语法扩展,可以让你在 JavaScript 文件中书写类似 HTML 的标签

  1. JSX - 使用react构造组件,babel(语法降级)编译——>转化js对象
  2. ReactDOM.render()方法将dom,插入到root
    3.JSX语法,最终会被编译为 createElement() 方法

JSX的注意点

只有一个根标签(虚拟dom对象需要一个根对象)
注意 1: 如果在 JSX 中给元素添加类, 需要使用 className 代替 class
类似:label 的 for属性,使用htmlFor代替
注意 2:在 JSX 中可以直接使用 JS代码,直接在 JSX 中通过 {} 中间写 JS代码即可
注意 3:在 JSX 中只能使用表达式,但是不能出现 语句!!!
注意 4:在 JSX 中注释语法:{/* 中间是注释的内容 */}
注意:JSX的语法需要通过 babel-preset-react 编译后,才能被解析执行

React组件

1.通过 JS函数 创建(无状态组件)

function WelcomeUI(props){
  // props ---> { username: 'zs', age: 20 }
  return (
    <div>
      <div>Welcome React</div>
      <h3>姓名:{props.username}----年龄是:{props.age}</h3>
    </div>
  )
}
// 给 WelcomeUI组件 传递 props:username 和 age
ReactDOM.reander(<WelcomeUI username="zs" age={20}></WelcomeUI>, ......)

JavaScript函数创建注意:
注意:1 函数名称必须为大写字母开头,React通过这个特点来判断是不是一个组件
注意:2 函数必须有返回值,返回值可以是:JSX对象或null
注意:3 返回的JSX,必须有一个根元素
注意:4 组件的返回值使用()包裹,避免换行问题 return ()

2.通过 class 创建(有状态组件)

1 如果一个组件仅仅是为了展示数据,那么此时就可以使用 函数组件
2 如果一个组件中有一定业务逻辑,需要操作数据,那么就需要使用 class 创建组件,因为,此时需要使用 state

import React, {Component} from 'react';

class StateDemo extends Component {
  state = {
           name: 'react',
           now: new Date()
       };
/* 两种方式都可以
   constructor(props) {
       super(props);
       this.state = {
           name: 'react',
           now: new Date()
       };
   }
*/
   render() {
       return (
           <div>
               <h1>hello {this.state.name}</h1>
               <div>当前时间是: {this.state.now.toLocaleString()}</div>
               <button onClick={()=>{this.setState({now: new Date()})}} >刷新时间</button>
           </div>
       );
   }
}

props和state区别

1. props

给组件传递数据 - 父子组件传递数据
组件中有一个只读的对象 叫做 props,无法给props添加属性
获取方式:函数参数WelcomeUI(props)或者 类自带属性props
作用:将传递给组件的属性转化为 props 对象中的属性
### 2.state状态即数据`
作用:用来给组件提供组件内部使用的数据
注意:只有通过class创建的组件才具有状态
注意:状态是私有的,完全由组件来控制
注意:不要在 state 中添加 render() 方法中不需要的数据,会影响渲染性能!

可以将组件内部使用但是不渲染在视图中的内容,直接添加给 this
注意:不要在 render() 方法中调用 setState() 方法来修改state的值

但是可以通过 this.state.name = 'rose' 方式设置state,但是不会更新render()(不推荐!!!!)

修改 state 的值,render()会更新

  // 方式一:
  this.setState({
    count: this.state.count + 1
  })

  this.setState({
    count: this.state.count + 1
  }, function(){
    // 由于 setState() 是异步操作,所以,如果想立即获取修改后的state
    // 需要在回调函数中获取
    // https://doc.react-china.org/docs/react-component.html#setstate
  });

设置 state 只会为下一次渲染变更 state 的值
一个 state 变量的值永远不会在一次渲染的内部发生变化
更新state:
1.设置 state 不会更改现有渲染中的变量,但会请求一次新的渲染。
2.React 会在事件处理函数执行完成之后处理 state 更新。这被称为批处理。
3.要在一个事件中多次更新某些 state,你可以使用 setNumber(n => n + 1) 更新函数。

二. 组件的生命周期

v2-c76edbbd7faf99ab9d470986ecc1411d_1440w.jpeg

函数的生命周期 主要分为三个阶段 :挂载(已插入真实 DOM)、更新(正在被重新渲染)、卸载(已移出真实DOM) .

class LDemo extends Component {
    constructor() {
        super();
        console.log('======执行了构造方法');
        // 构造方法中直接给state赋初始值 不能执行setState
        this.state = {name:'react'}
    }

    componentWillMount() {
     '注意:无法获取页面中的DOM对象,还没被挂载'
     '注意:可以调用 setState() 方法来改变状态值,用途:请求获取数据'
        console.log('=======组件将要挂载,执行了componentWillMount')

    }

    componentDidMount() {
        console.log('======组件挂载到dom节点完成,执行了componentDidMount方法');
  `1 组件已经挂载到页面中
   2 可以进行DOM操作,比如:获取到组件内部的DOM对象
   3 可以发送请求获取数据
   4 可以通过 setState() 修改状态的值
   注意:在这里修改状态会重新渲染render()
`
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log('=====执行了shouldComponentUpdate 组件在受到props或者state更新要判断是否执行render方法刷新视图, 返回false则不执行render');
        // 当state中name变为vue时,视图不更新
        if (nextState.name === 'vue') {
            return false;
        }
        return true;
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log('=====组件更新完成之后,执行了componentDidUpdate')
    }

    componentWillUnmount() {
        // 一般用于处理消除定时器、订阅
        console.log('======组件将要移除时,执行componentWillUnmount')
    }


    render() {
 `不要在render方法中调用 setState() 方法,否则会递归渲染
   原因说明:状态改变会重新调用render(),render()又重新改变状态`
    console.log('======执行了render方法');
     mytext = React.createRef() //关联dom
    render() {
        return (
            <div>
                <input type="text" ref={this.mytext} defaultValue="asdad" />
                <button onClick={
                    () => { console.log(this.mytext.current.value); }
                }>获取Value</button>
                <button onClick={() => {
                    this.mytext.current.value = ""
                }}>重置</button>
            </div >
        )
    }

}

事件绑定中的this

1 通过 bind 绑定
2 通过 箭头函数 绑定

// 自定义方法:
handleBtnClick(arg1, arg2) {
  this.setState({
    msg: '点击事件修改state的值' + arg1 + arg2
  })
}

render() {
  return (
    <div>
原理:bind能够调用函数,改变函数内部this的指向,并返回一个新函数
说明:bind第一个参数为返回函数中this的指向,后面的参数为传给返回函数的参数
      <button onClick={
        // 无参数
        // this.handleBtnClick.bind(this)
        // 有参数
        this.handleBtnClick.bind(this, 'abc', [1, 2])
      }>事件中this的处理</button>

##箭头函数中的this由所处的环境决定,自身不绑定this
   <input type="button" value="在构造函数中绑定this并传参"
     onClick={() => { this.handleBtnClick('参数1', '参数2')}
    } />

    </div>
  )
}

传递给事件处理函数的函数应直接传递函数名handleClick,而非调用 handleClick()

<button onClick={handleClick}> 正确 |
handleClick 函数作为 onClick 事件处理函数传递。这会让 React 记住它,并且只在用户点击按钮时调用你的函数。
<button onClick={handleClick()}>错误 |
handleClick() 中最后的 () 会在 [渲染] 过程中 立即 触发函数,即使没有任何点击。这是因为在 [JSX {}]之间的 JavaScript 会立即执行。

组件通讯

父 -> 子:props
子 -> 父:父组件通过props传递回调函数给子组件,子组件调用函数将数据作为参数传递给父组件
兄弟组件:因为React是单向数据流,因此需要借助父组件进行传递,通过父组件回调函数改变兄弟组件的props

state
1.React 会等到事件处理函数中的 所有 代码都运行完毕再处理你的 state 更新。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容