React系列(二) - react基础知识

674 阅读3分钟

React系列(一)-脚手架创建项目
React系列(三) - DOM操作
React系列(四) - react生命周期

本章内容主要参考React中文文档[react.docschina.org/docs/hello-…] 算是小白入门的基础,了解React基本用法。
基于create-react-app创建的项目,删掉暂时用不到的文件,项目结构简易图

1.png

1. Hello World

一个简单的例子

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
    <h1>Hello World</h1>,
    document.getElementById('root')
);

结果:

2.png

ReactDOM.render方法是将模板转换为HTML语言,并添加到指定DOM节点中,接收两个参数 render(template, targetDOM) 第一个是创建的模板,例如<h1>Hello Wrold</h1>;第二个是添加模板到指定的DOM元素位置,上面的代码是将模板添加到root 这个节点下

2. JSX简介

React中使用JSX代替常规的JavaScript。需要经过babel编译,才能在浏览器中使用。create-react-app脚手架中默认有该配置,插件是 @babel/preset-react

声明变量

// 声明一个变量
const element = <h1>Hello World</h1>;
ReactDOM.render(
    element,
    document.getElementById('root')
);

变量中的表达式

import React from 'react';
import ReactDOM from 'react-dom';

const name = '张三';
const element = <h1>Hello { name }</h1>
ReactDOM.render(
    element,
    document.getElementById('root')
);

ps: 在JSX中,你可以在大括号({})放置任何有效的JavaScript表达式

3. JSX中条件渲染

function todo(user) {
    if (user) {
        return <h1>true</h1>
    } else {
        return <h1>false</h1>
    }
}

三元运算符

function Todo() {
    const isTrue = true
    return (
        <div>
            { isTrue? <h1>true</h1> :
             <h1>false</h1>
            }
        </div>
    )
}

4. 列表渲染

import React from 'react';
import ReactDOM from 'react-dom';

const numbers = [1,2,3,4,5,6]
const elements = numbers.map( item => <p>{item}</p>)

ReactDOM.render(
    element,
    document.getElementById('root')
)

在类组件中

import React from 'react';
class Todo extends React.Component {
    const numbers = [1,2,3,4,5,6]
    render() {
        return (
            <div>
                <ul>
                    {
                        numbers.map((item, index) => {
                            return <li key={index}>{item}</li>
                        })
                    }
                </ul>
            </div>
        )
    }
}

5. 事件处理

React中事件处理和原生HTML类似,但语法上有一点不同:

  • React事件采用小驼峰,而不是纯小写
  • 使用JSX语法时需要传入一个函数作为事件处理函数,而不是字符串 传统HTML:
<button onclick="clickEvent()">
    按钮
</button>

JSX语法:

<button onClick={clickEvent}>
    按钮
</button>

在react中不能通过return false阻止默认行为,必须使用preventDefault

// 在HTML中阻止默认跳转
<a href="#" onclick="console.log('test'); return false">链接</a>

// JSX语法中
function App() {
    function handleClick(e) {
        e.preventDefault();
        console.log('test')
    }
    
    return (
        <a href="#" onClick={handleClick}>链接</a>
    )
}

几种事件处理写法

  • 箭头函数写法(我喜欢的)
import React from 'react';

class Todo expends React.Component {

    handleClick = (e) => {
        console.log(e)
    }
    
    render() {
        return (
            <button onClick={this.handleClick}>点击</button>
        )
    }
}

export default Todo;
  • this.xxx.bind
import React from 'react';

class Todo expends React.Component {

    handleClick(e){
        console.log(e)
    }
    
    render() {
        return (
            <button onClick={this.handleClick.bind(this)}>点击</button>
        )
    }
}

export default Todo;
  • 在constructor绑定
import React from 'react';

class Todo expends React.Component {
    
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }
    
    handleClick(e){
        console.log(e)
    }
    
    render() {
        return (
            <button onClick={this.handleClick}>点击</button>
        )
    }
}

export default Todo;

6. 表单

React中的表单处理与Vue区别比较大,个人更喜欢Vue

  • Vue表单处理
// Vue3.0以下的版本
<template>
    <div>
        <input type="text" v-model="value" />
    </div>
</template>

export default {
    name: 'app',
    data() {
        return {
            value: ''
        }
    }
}

在data中定义一个value,使用v-model可以直接实现双向绑定

  • react表单
import React from 'react';

class Todo extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            value: ''
        }
    }
    
    handleChange = (e) => {
        // 更新的时候,不能直接使用this.state.value = xxx 不能直接赋值
        // 使用setState更改
        this.setState({ value: e.target.value })
    }

    render() {
        return (
            <div>
                <input type="text" value={this.state.value} onChange={this.handleChange} />
                <p>{this.state.value}</p>
            </div>
        )
    }
}

7. state

state用于类组件中的状态,在页面上的交互,实现不同的状态,然后去渲染状态,页面的数据与UI保持一致。 通俗的讲就是定义变量,类似Vue中的data函数

  • 初始化state
constructor(props) {
    super(props);
    this.state = {
        name: '张三'
    }
}

// 使用
render() {
    return (
        <div>{this.state.name}</div>
    )
}
  • 更新state
// this.state.name = xxx 这样是无法更新视图UI的
// 正确用法
this.setState({name: 'xxx'})

8. 组件和props

组件可以将UI拆分为独立的代码片段,便于复用。从概念上来说,类似JavaScript中的函数,接收任意入参(props)

函数组件和类组件

  • 函数组件
function Hello(props) {
    return <p>Hello, {props.name}</p>
}
  • 类组件
class Hello extends React.Component {
    render() {
        return (
            <p>Hello, {this.props.name}</p>
        )
    }
}

上面效果是等效的 ps:后面文章说明两种组件区别

  • props传值
import React from 'react';
import Hello from './hello'; // 引入组件

class App extends React.Component {
    
    render() {
        return (
            <div>
                <Hello name='张三' />
            </div>
        )
    }
}

export default App;

// Hello组件上的name属性就是传过去的值,在组件中,通过props获取。例如props.name(函数组件)或者this.props.name(类组件)