React语法及使用

本文详细介绍了React的基本用法,包括如何使用React渲染页面、DOM元素嵌套,JSX语法的启用与本质,以及组件的创建、样式绑定和事件处理。讲解了在React中使用构造函数和class创建组件的区别,并探讨了组件生命周期及其方法的应用。此外,还讨论了如何在项目中配置webpack以支持jsx和样式文件,并展示了如何利用create-react-app快速创建React项目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.使用React渲染一个最基本的页面

//1.导入
import React from "react";//创建组件、虚拟DOM元素,生命周期
import ReactDOM from 'react-dom';//把创建好的组件和虚拟DOM放到页面上去展示的

//2.创建虚拟DOM元素
//参数1:创建的元素的类型
//参数2:是一个对象或null,表示当前这个DOM元素的属性
//参数3:子节点
//参数n:其他子节点
const myh1 = React.createElement('h1',{id:'myh1',title:'this is myh1'},'这是用react创建的');

//3,使用ReactDOM把虚拟DOM渲染到页面上
//参数1:要渲染的那个虚拟DOM元素
//参数2:页面上的一个容器
ReactDOM.render(myh1,document.getElementById('container'));

2.实现DOM元素嵌套渲染

const myh1 = React.createElement('h1',{id:'myh1',title:'this is myh1'},'这是用react创建的');
const mydiv = React.createElement('div',{id:'mydiv',title:'this is mydiv'},'这是用react创建的div',myh1);
ReactDOM.render(mydiv,document.getElementById('container'));

3.JSX语法

启用JSX语法

(1)安装babel插件,执行以下命令

cnpm i babel-core babel-loader babel-plugin-transform-runtime -D
cnpm babel-preset-env babel-preset-stage-0 babel-preset-react -D

(2)在webpack.config.js文件中写入第三方配置规则

//webpack默认只能打包处理.js后缀名类型的文件,像.png,.vue等无法处理,所以要配置第三方的loader
module.exports = {
    mode:"development",
    plugins:[
        htmlPlugin
    ],
    module:{//所有第三方模块的配置规则
        rules:[//第三方匹配规则
            //千万别忘记添加exculde排除项
            {test:/\.js|jsx$/,use:'babel-loader',exclude:/node_modules/,}
        ]
    }
}

(3)在项目根目录下添加.babelrc配置文件,写入以下代码

{
    "presets":["env","stage-0","react"],
    "plugins":["transform-runtime"]
}

JSX语法的本质:

并不是直接把JSX渲染到页面上,而是内部先转换成立creatElement形式后再渲染的

在JSX中可以混合写入JS表达式,但是要把JS代码写到{}中

let a = -2;
let str = '你好';
let boo = true;
let title = '999';
const h1=<h1>这是h1</h1>
const arr = [
	<h2>这是h2</h2>,
	<h3>这是h3</h3>
.]
ReactDOM.render(<div>
	//渲染数字
	{a+2}
	//渲染字符串
	{str}
	//渲染布尔值
    {boo ? '条件为真':'条件为假'}
    //为属性绑定值
    <div title = {title}></div>
    //渲染JSX元素
    {h1}
    //渲染JSX数组
    {arr}
</div>,
    document.getElementById('container')
)

将普通字符串转为JSX数组并渲染到页面上
(1)在外部使用forEach循环

      const arr = ['小王','小路','小刘','小样'];
      const newArr=[];
      arr.forEach(item => {
            newArr.push(<h3>{item}</h3>);
        });
       ReactDOM.render(
        <div>
            {newArr}
            </div>,
            container
    )

(2)在渲染内部使用map函数(推荐)

        const arr = ['小王','小路','小刘','小样'];
        ReactDOM.render(
        <div>
            {arr.map(item=><h3>{item}</h3>)}
            </div>,
            container
        )

注意:1.Reac中用className代替class,用htmlFor代替for循环
2、在JSX创建DOM的时候,所有的节点,必须由唯一的根元素进行包裹
3、在JSX语法中,标签必须成对出现,如果是单标签,则必须自闭和

React中创建组件的两种方式

注意:组件名称首字母必须大写

第一种 使用构造函数来构建组件
        function  Hello() {
        	//在组件中必须返回一个合法的JSX虚拟DOM元素
            return <h1>这是hello组件</h1>    
        }
        ReactDOM.render(
        <div>
             {/*直接把组件的名称,以标签的形式丢到页面上即可*/}
            <Hello />
            </div>,
            container
        )
第二种 使用class创建组件

最基本的组件结构

//如果要使用class定义组件,必须让自己的组件继承自React.Component
class Hello extends React.Component {
    //在组件内部,必须有render函数
    render(){
        //render函数中,必须返回合法的JSX虚拟DOM结构
        return <div><h1>这是class创建的组件</h1></div>
    }
}

在class关键字创建的组件中,如果想使用外界传递过来的props参数,不需要接收,直接通过this.props.xxx访问

class People extends React.Component{
    render(){
        //在class组件内部,this表示当前组件的实例对象
        return <h1>{this.props.name}---{this.props.age}</h1>
    }
}
var user = {
    name : 'yang',
    age : 18
}
ReactDOM.render(
    <div>
        <People {...user}></People>
    </div>,
    document.getElementById('container')
    );
使用class创建类

注意:在class的{}内只能写构造器,静态方法和静态属性,实例方法

class Hello {
    //这是类的构造器,每一个类都有一个构造器,如果没有手动指定,,认为类内部有一个隐形的空构造器
    //构造器的作用就是,每当new这个类的时候,必然会优先执行构造器中的代码
    constructor(name,age){
        //实例属性(通过new出来的实例访问到的属性)
        this.name = name;
        this.age  = age;
    }
    //在class内部听过static修饰的属性,为静态属性(直接通过构造函数进行访问)
    static info = 'eee';
    //这是Hello的实例方法,挂载到原型对象上
    say(){};
    //这是静态方法
    static show(){}
}

使用extends实现子类继承父类

//这是父类
class People{
    constructor(name,age){
        this.name = name;
        this.age = age
    }
}
//这是子类 美国人
//在class类中,可以使用extends关键字实现子类继承父类
class American extends People{  
}

constructor构造器中super函数的使用

//这是父类
class People{
    constructor(name,age){
        this.name = name;
        this.age = age
    }
}
//这是子类 美国人
//在class类中,可以使用extends关键字实现子类继承父类
class American extends People{ 
    constructor(name,age){
        //如果一个子类通过extends关键字继承了父类,那么在子类的constructor构造函数中,必须优先调用一下super()
        //super是一个函数,其实就是父类中constructor构造器的一个引用
        //必须传递参数
        super(name,age)
    } 
}

将组件抽离为单独的JSX文件

(1)在src代码源文件下新建一个名为components的文件夹存放组件
(2)每一个组件都是一个后缀名为.jsx的文件
(3)每个组件前面必须引入React包,最后在文件内需要把组件导出(export default)
(4)需要使用此插件时需要导入(例:import Hello from ‘路径名’)

配置webpack从而在导入文件时可以省略.jsx后缀名

配置webpack设置根目录

在webpack.config.js中写入如下代码

  resolve:{
        extensions:['.js','.jsx','.json'],//表示这几个文件的而后缀名可以不写,自动补全
        alias:{//表示别名
            '@':path.join(__dirname,'./src')//这样,@就表示项目根目录src这一层路径
        }
    }

两种创建组件方式对比

注意:1.使用class关键字创建的组件,叫“有状态组件”,有自己的私有数据(this.state)和生命周期函数,
——如果一个组件需要有自己的私有数据,则推荐使用class创建的组件
2.使用function创建的组件,叫“无状态组件”,只有props,没有自己的私有数据和生命周期函数
——如果一个组件不需要有私有的数据,则推荐使用无状态组件
3.props中的数据都是外界传递过来的,都是只读的,不能重新赋值
state中的数据都是组件私有的(通过AJAX获取回来的数据,一般是私有数据),都是可读可写的

再组件中使用样式

行内样式

在这里插入代码片
<h1 style={{margin:'0 auto',color:'red'}}>刚睡醒</h1>//字符串形式的值必须带引号

样式封装

const styles = {
    itemStyle : {border:'1px dashed #ccc',margin:'10px',padding:'10px',boxShadow:'0 0 10px #ccc'},
    userStyle : {fontSize:'14px'},
    contentStyle : {fontSize:'12px'}
}
function CmtItem(props){
    return <div style={styles.itemStyle}>
             <h1 style = {styles.userStyle}>评论人:{props.user}</h1>
             <p style={styles.contentStyle}>评论内容:{props.content}</p>
             </div>
}

将样式表抽离为单独的JS文件

在webpack中不支持识别css文件,所以要执行以下命令

(1)下载包

cnpm install style-loader css-loader -D

(2)在webpack.config.js文件中配置环境

   module:{//所有第三方模块的配置规则
        rules:[//第三方匹配规则
            //千万别忘记添加exculde排除项
            {test: /\.js|jsx$/, use:'babel-loader', exclude:/node_modules/,},
            {test:/\.css$/,use:['style-loader','css-loader']},//打包处理CSS样式表的第三方loader
        ]
    },

注意在组件中直接导入CSS样式表,默认是在全局上,整个项目都会生效
解决方法:为样式表通过modules参数启用模块化
**css模块化只针对类选择器和ID选择器生效,不会对标签选择器模块化
**

  module:{//所有第三方模块的配置规则
        rules:[//第三方匹配规则
            //千万别忘记添加exculde排除项
            {test: /\.js|jsx$/, use:'babel-loader', exclude:/node_modules/,},
            {test:/\.css$/,use:['style-loader','css-loader?modules']},//在css-loader后通过?追加参数modules,则是为CSS样式表启用模块化
        ]
    },

如何引用

import cssObj from '@/components/CmtList.css';//title="_2KMjyWWi8Ngzkw70VqnVTm"(随机生成乱码,模块化)
  <h1 className={cssObj.title}>这是评论列表组件</h1>

可以使用localIdentName自定义生成的类名格式

            {test:/\.css$/,use:['style-loader','css-loader?modules&localIdentName=[path]']}

可选的参数:
(1)[path]:表示样式表相对于项目根目录所在路劲
(2)[name]表示样式表文件名称
(3)[local]表示样式的类名定义名称
(3)[hash:length]表示32位的hash值,length可以指定长度
可以这样写{test:/\.css$/,use:['style-loader','css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]']}
t通过local和global设置类名是否被模块化
被:global()包裹起来的类名不会被模块化,属于全局

:global(.test){
    font-size: 120px;
    color: aqua;
}

被:local()包裹起来的类名单独指定被模块化

:local(.test){
    font-size: 120px;
    color: aqua;
}

在项目中,自己写的样式表一般以.scss或.less为后缀,而第三方的样式表一般以.css为后缀名,所以我们只为.scss或.less文件启用模块化,这样引用第三方样式表(如bootstrap)就使用起来比较方便简单
(1)先装sass的包

cnpm install sass-loader node-sass -D

(2)再配置环境

  {test:/\.scss$/,use:['style-loader','css-loader?modules&localIdentName=[path]','sass-loader']}//打包处理.scss文件的loader

第三方样式表就可以这样引入

<button className="btn btn-primary">按钮</button>

React中绑定事件

——在React中有一套自己的事件绑定机制,事件名为小驼峰命名
——为事件绑定处理函数的格式onClick={function(){ }}
——也可以将函数抽离出来

 render(){
        return <div>           
                今天学到了不少东西,
            <hr/>,
            {/* 注意这里后面不能加() */}
            <button onClick={this.myhandle}>按钮</button>
            {/*如果是箭头函数后面要加()*/}
             <button onClick={()=>{this.myhandle()}}>按钮</button>
        </div>
    }
    //这是一个实例方法
    myhandle(){
        console.log('你好');
    }
规范写法
import React from 'react';
export default class BindEvent extends React.Component{
    constructor(){
        super();
        this.state={};
    }

    render(){
        return <div>
            <h1>马上要走了</h1>
            <hr/>
            <button onClick={()=>{this.myHandle('啊哈是')}}>按钮</button>
        </div>
    }
    myHandle= (item)=>{
        console.log('show方法'+item);
    }
}

使用this.setState修改state的数据

——在React中,如果想为state中的数据重新赋值,不要使用this.state=xxx;应该调用React提供的以下方法

 this.setState({
          name:'zhang'
      })

React组件生命周期

组件的生命周期可分成三个状态:

(1)Mounting:已插入真实 DOM
(2)Updating:正在被重新渲染
(3)Unmounting:已移出真实 DOM

生命周期的方法有:

(1)componentWillMount 在渲染前调用,在客户端也在服务端。在组件挂载到页面前执行

(2)componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。

(3)componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

(4)shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
可以在你确认不需要更新组件时使用。

(5)componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

(6)componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。

(7)componentWillUnmount在组件从 DOM 中移除之前立刻被调用。

生命周期应用场景

(1)shouldComponentUpdate()函数用于性能优化
(2)在componentDidMount()函数里发送AJAX请求

使用create-react-app组件创建一个项目

(1)安装create-react-app

npm install create-react-app -g

(2)创建一个项目

create-react-app 项目名

(3)启动项目

npm run start
//或者 yarn start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值