学习笔记——react基础功能学习


react框架是当前较为流行的一种框架,它主要用于较为大型的项目。react框架与vue框架类似。以下主要学习了以下vue的指令在react中如何实现。

1.react的下载: 

在命令窗口,下载react脚手架包:

yarn global add create-react-app

 2.创建项目:

在命令窗口,输入以下内容创建react项目:

create-react-app  项目名

3.了解项目:

使用webStorm,VS Code或者HBulider 打开你的项目。可以看到一些文件,其中

package.json里面是项目一些基本的配置,如如何开始、打包项目,项目的依赖包等。

src文件夹是我们主要的写代码的地方。在src中,index.js文件是根实例,将根组件App渲染到public文件夹中index.html中的挂载点上。其内容比较固定。

// 使用jsx对象(例如:<App />)时,必须引入react
import React from 'react';
import ReactDOM from 'react-dom';
// 导入根组件
import App from './App.jsx';

// 第一个参数;要渲染什么。第二个参数:要渲染到哪里
ReactDOM.render( <App />, document.getElementById('root'));

src文件夹中的App.jsx是根组件。定义根组件有两种方法:类组件,函数组件。

什么是jsx对象?相对于vue中的template。

react组件必须要指定一个render函数,该函数必须要返回一个jsx对象或null。

以下使用的是类组件。

// react组件的自定义就是要继承自React.Component的类
import React, { Component } from 'react';

class App extends Component {
    constructor() {
        super();                  // 可以使用父组件中的构造函数
        this.state = {            // 放需要渲染的数据
                            
        }
    }
    render() {                    // return中写html代码,返回jsx对象
        return {(                 // 写html代码时,可以用()包裹
            <div><div>            // 只有一个根节点
        )};
    }
}

src文件夹中的App.css是修饰根组件的样式,不过若多个css文件夹中有相同的class值,会造成渲染混乱。所以我们一般使用App.module.css,准确找到需要的样式。 

import style from './App.module.css';     // 导入样式文件

render() {
    return {
        <div className={style["container"]></div>
    };
}

 4.基础功能实现:

在以下功能中,使用的数据都来自constructor中的this.state中。函数来自与constructor,render同级的自定义函数。

1.类似vue中的v-text指令:

<span>{this.state.name}</span>

2.类似vue中的v-if指令:

<div>
    {this.state.isShow && (    // this.state.isShow为真时,显示后面的内容
        <div>显示内容</div>
    )}
</div>

3.类似vue中的v-if + v-else指令:

<div>
    {this.state.isShow ? (
        <div>为真显示的内容</div>
    ) : (
        <div>为假显示的内容</div>
    )}
</div>

4.类似vue中的v-if + v-else-if  + v-else指令:

可以通过函数间接实现该指令,不过函数要返回一个jsx对象。

// render()函数周围
judge() { return jsx对象 }
// render()函数returnjsx对象中
<div>
    {this.judge}
</div>

5.类似vue中的v-for指令:

<ul>
    {this.state.data.map((item,i) => (        // 简单类型的数组
        <li key={i}>{item}</li>
    ))}
</ul>

6.类似vue中的v-show指令:

无法直接实现,动态改变class值来实现。在CSS中设置一个class值show:display block;另一个class值hidden: display: none;来回切换class实现v-show指令。

<span className={this.state.isShow ? style["show"] : style["hidden"]}>显示</span>

7.类似vue中的v-bind指令:

可以实现动态和静态class值同时存在。

// 共有两种方式实现:
<span className={["aaa", this.state.isShow ? style["show"] : ""].join(" ")}>显示</span>

<span className={`aaa ${ this.state.isShow ? style["show"] : "" }`>显示</span>

8.类似vue中的v-on指令:

给标签绑定事件。使用on+事件名,例如点击事件onClick。

事件绑定不传参(默认传事件对象e):

<button onClick={this.clickHandler}>点我</button>

事件绑定传参(写成箭头函数):

<button onClick={() => this.clickHandler2(100)}>点我</button>

使用事件绑定时还需要注意函数中this指针的指向问题。若想让react事件绑定函数中的this指针指向当前的组件本身,有三个方法:

1.在当前组件的构造函数中进行bind调用,绑死this。

优点:当该函数为父组件传给子组件的函数时,父组件中函数的刷新不会导致子组件中函数无意义的刷新。

缺点:需要再constructor中书写额外的代码

constructor() {
    super();
    this.state = {};
    this.clickHandler = this.clickHandler.bind(this)
}

clickHandler() {}

<button onClick={this.clickHandler}></button>

 2.在绑定函数时,直接用bind绑定this指针。

优点:不需要在constructor中写额外的代码。

缺点:当该函数为父组件传给子组件的函数时,父组件中函数的刷新,都会执行bind表达式产生一个新的与上一个相同的函数,但子组件会认为这是一个不同的函数,导致子组件无意义的刷新。

clickHandler() {}

<button onClick={this.clickHandler.bind(this)}></button>

3.利用ES6类定义高级特性,在类定义函数时,使用箭头函数,让this绑死当前组件。

clickHandler = () => {};

<button onClick={this.clickHandler}></button>

 9.修改state中的数据:

必须使用this.setState()来修改state中的数据。

constructor() {
    super();
    this.state = {
        name: '张三',
        arr: [{id: 1, name: '张三'}, {id: 2, name: '李四'}],
        obj: { id: 3, name: '王五' }
    };
}

// 简单修改数据
this.setState({ name: '李四' });    // 运行后state中的name数据会发生改变'李四'
// 运行后state中obj中的值会变成'李四'
this.setState({ obj: Object.assign({}, this.state.obj, { name: '李四' }) })

// 操作arr
let arr = this.state.arr;
arr[0].name = "李四";
this.setState({ arr });
// 运行后,state中的arr的第一个对象中的name值为李四

this.setState()中可以是对象,也可以是函数。其区别在于:

如果是对象(this.setState({}))的话,在同一段同步代码中不论迭代多少次,它只执行最后一次的操作。

如果是对象(this.setState(state => {}))的话,在同一段同步代码中后面setState中的数据要用到前面setState中的结果。

this.state = {
    a: 0,
    b: 0
}

for(let i = 0; i < 100; i++) {
    this.setState({ a: this.state.a + 1 });
    this.setState(state => { a: state.a + 1 });
}

// 操作执行结束后,a: 1, b: 100

 以上是今天学习react框架的成果。

猜你喜欢

转载自blog.csdn.net/qq_41339126/article/details/109456824