React快速入门

React快速入门

不使用脚手架

引入js:

<script src="./js/react.development.js"></script><script src="./js/react-dom.development.js"</script>

写法:

<div id="root"></div>
    <script>
        //创建标签
        let h1=React.createElement('h1',{name:'h1-name',price:200},'当前h1标签的内容')
        let root=document.querySelector("#root");
        ReactDOM.render(h1,root);//挂载(标签,挂载位置)
    </script>

这样即可实现div的id为root标签上放入h1标签

脚手架

安装与创建项目并启动

老式安装方法:

cnpm install -g create-react-app    //安装
create-react-app 项目名称 //创建项目

推荐使用的安装chai方法

//npx无需先安装脚手架(推荐使用)
            npx create-react-app 项目名 //有就会直接创建,没有则会安装再创建

启动项目:

npm start	//启动

简单使用

在脚手架创建完项目后,在index.js(入口文件)进行操作

当然也可以新建一个js操作,不过需要在入口文件导入…

const root = ReactDOM.createRoot(document.getElementById('root'));//得到dom元素

//使用函数进行创建dom
function Hello(props){  //函数名必须要大写开头
  return <h1>helloworld</h1>;
}
//挂载
root.render(
  <Hello />  
);
    
//方式2
    //let root=document.querySelector("#root");
	//ReactDOM.render(<Hello />,root)

以上代码即可实现页面显示的内容为h1标签的helloworld

JSX

React 使用 JSX 来替代常规的 JavaScript。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

我们不需要一定使用 JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

使用className定义类名

简单的

//jsx
//简易的jsx
const title=<h1 price="200">Hello React~</h1>

root.render(
	title
)

复杂的

通过{}获取变量值

使用()将多个复杂层次的标签包裹起来

//复杂的jsx
let name='碰磕'
let age=18
let div=(
  <div className='box'> 
    <h1>hello JSX</h1>
    <p style={{'color':"red"}}>name={name},年龄={age}</p>
  </div>
)
//挂载
root.render(
	div
)

条件渲染

通过函数判断返回的内容并显示

//条件渲染
let flag=true;
function Login(user){
  if(flag){
    return <u>欢迎{user}登录</u>
  }
  return <u>还没登录呢</u>
}
const div=(
  <div>
    <h1>条件渲染</h1>
    {Login('碰磕')}
  </div>
)

循环

简单的循环数组

//循环
const number=[1,23,312,23,66];
//这里演示map方法,当然还有很多种
let ok =number.map((num)=>{
  return <li>{num}</li>; //jsx写法
})
root.render(
	<ul>{ok}</ul>
)

循环数组中的对象(常见)

const sz=[
  {uid:1,uname:'碰磕'},
  {uid:2,uname:'Student'},
  {uid:3,uname:'Study'}
]
let ok2 =(
<div className='box' >
  <ul>
  {sz.map((val)=>{
  return <li key={val.uid}>uid:{val.uid},uname:{val.uname}</li>;
  })}
  </ul>
</div>
)
root.render(
	ok2
)

组件的三种定义方式

因为是组件,所以挂载时都要加上标签

例如Fun则是

root.render(
	<Fun />
)

函数组件

函数组件中的事件在组件内定义

通过{事件名}调用

//函数组件
function Fun(){
  //点击函数
  function dj(){
    alert('点我干啥??')
  }
  return (
    <div className='box'>
    <b>我是组件,可重复利用</b>
    <button onClick={dj}>Click</button>
    </div>
  )
}
root.render(
	<Fun />
)

类组件

语法:class 组件名 extends React.Component{

​ render(){

​ return()

​ }

}

类组件的组件在类内定义,通过this.事件名调用

//类组件
class Box2 extends React.Component{
dj(){
alert('我是类组件')
}
 //渲染
render(){
return(
<div className='box'>
  <b>我是组件2,可重复利用</b>
  <button onClick={this.dj}>Click</button>
</div>
)
}
}
root.render(
<Box2 />
);

独立定义类组件(常用)

创建一个文件Box.js在该文件内定义

import React from "react"
//类组件
class Box3 extends React.Component{
 dj(){
   alert('我是类组件独立文件')
 }
 render(){
   return(
     <div className='box'>
       <b>我是组件3,可重复利用</b>
       <button onClick={this.dj}>Click</button>
     </div>
   )
 }
}
export default Box3//导出

在入口文件导入并使用:

import Box3 from './Box'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Box3 />
);

这样即可使用成功~

state(用于绑定数据)

简单应用

完成计算器,+或者-改变数据,并且可通过函数传参

  • 可以在构造方法里边定义state也可以在构造方法外部定义
  • 获取state数据:this.state.属性名
  • 修改state数据:this.setState({})-------类似微信小程序写法
  • 传参函数this.函数名.bind(this,参数)----->必须传一个this

Tip:需要使用箭头函数,this指向问题-普通函数拿不到this,通过this得到state

class NumberCount extends React.Component{
    //构造方法
    constructor(){
        super();
        this.state={
            count:66
        }
    }
    //由于this在普通函数为undefined,所以改为箭头函数 
    jia=()=>{
        //不能直接更新
        // this.state.count=this.state.count+1 
        this.setState({ //类似于微信小程序写法
            count:this.state.count+1
        })
    }
    //传参函数,参数中必须带this,通过bind进行传参
    jian=(num)=>{
        console.log("num=",num);
    }
    //渲染
    render(){
        return(
            <div>
            <h1>计数器</h1>
            <h3>{this.state.count}</h3>
            <button onClick={this.jia}>+1</button>
            <button onClick={this.jian.bind(this,4)}>-</button>
            </div>
        )
    }   
}
export default NumberCount;

导出后在index中使用即可

表单与状态绑定的应用

实现类似vue中的双向绑定,通过修改表单中的值,state的值也会跟着变

**Tip:**文本框被改变事件不绑定会报错

/**
 * 表单--绑定-->状态
 */
import React from 'react';
import ReactDOM from 'react-dom/client';

class Mytxt extends React.Component{
    state={
        stname:'temo',
        city:'吉安市',
        area:'江西省',
        flag:true
    }
    //文本框被改变事件(不绑定会报错)
    txthandle=(e)=>{
        //绑定stname值(实现vue中的双向绑定)
        this.setState({
            stname:e.target.value
        })
        console.log(e.target.value);
    }

    areahandle=(e)=>{
        this.setState({
            area:e.target.value
        })
        console.log(this.state.area);
    }

    selhandle=(e)=>{
        this.setState({
            city:e.target.value
        })
        console.log(this.state.city);
    }

    checkhandle=(e)=>{
        this.setState({
            flag:e.target.checked
        })
        console.log(this.state.flag);
    }
    render(){
        return(
            <div>
                <h1>表单测试</h1>
                <p>输入框:<input onChange={this.txthandle} type='text' value={this.state.stname} /></p>
                <p>文本域:<textarea onChange={this.areahandle} value={this.state.area}></textarea></p>
                <p>
                下拉列表-城市选择:
                    <select onChange={this.selhandle} value={this.state.city}>
                        <option value="南昌市">南昌市</option>
                        <option value="宜春市">宜春市</option>
                        <option value="吉安市">吉安市</option>
                    </select>
                </p>
                <p>
                    复选框:<input type="checkbox" checked={this.state.flag} onChange={this.checkhandle} />是否选择
                </p>
            </div>
        )
    }
}

export default Mytxt

优化(将所有函数合并一个函数)

上方表单每个组件都对应一个函数,看着都不雅观,上方代码可发现:

  • 除了下拉框其它都是修改value
  • 由此得出可以通过属性传值修改对应的state属性
  • 开始实现~
/**
 * 优化表单绑定的处理函数  ----多个组件用同一个
 */
import React from 'react';
import ReactDOM from 'react-dom/client';

class Mytxt2 extends React.Component{
    state={
        stname:'temo',
        city:'吉安市',
        area:'江西省',
        flag:true
    }

    //统一处理
    formhadle=(e)=>{
        let t=e.target;//获取目标对象
        let val=t.type == 'checkbox'?t.checked:t.value//如果市复选框则是checked,其他的是value
        this.setState({
            [t.name]:val
        })
        console.log(this.state.area);
    }
   
    render(){
        return(
            <div>
                <h1>表单测试</h1>
                <p>输入框:<input name="stname" onChange={this.formhadle} type='text' value={this.state.stname} /></p>
                <p>文本域:<textarea name="area" onChange={this.formhadle} value={this.state.area}></textarea></p>
                <p>
                下拉列表-城市选择:
                    <select name="city" onChange={this.formhadle} value={this.state.city}>
                        <option value="南昌市">南昌市</option>
                        <option value="宜春市">宜春市</option>
                        <option value="吉安市">吉安市</option>
                    </select>
                </p>
                <p>
                    复选框:<input name="flag" type="checkbox" checked={this.state.flag} onChange={this.formhadle} />是否点赞
                </p>
            </div>
        )
    }
}

export default Mytxt2

通过name属性传对应的value所绑定的state中对应的属性

再用三元表达式对复选框的进行一个判断从而一一对应的修改

练习:实现留言板

思路:

  • state中的属性讲解:
    • gname:留言昵称
    • gmsg:留言内容
    • guestbookAllmsg:存放留言信息的数组
  • 函数讲解:
    • addmsg():发表留言,每发表留言都对guestbookAllmsg数组进行改变
    • isHave():实时判断留言板是否有留言从而显示对应的内容
      • 没有留言则显示:暂无评论,快去评论吧~
      • 有留言则循环使用无序列表显示留言(遍历数组)
/**
 * 留言板
 */
 import React from 'react';
import './index.css'

class GuestBook extends React.Component{
    state={
        gname:'',
        gmsg:'',
        guestbookAllmsg:[]
    }
    formhadle=(e)=>{
        let t=e.target;//获取目标对象
        let val=t.type == 'checkbox'?t.checked:t.value//如果市复选框则是checked,其他的是value
        this.setState({
            [t.name]:val
        })
    }
    //发表留言
    addmsg=(e)=>{
        if(this.state.gname!=""&&this.state.gmsg!=""){
            let guest={
                'gname':this.state.gname,
                'gmsg':this.state.gmsg
            }
            this.setState({
                guestbookAllmsg:[guest,...this.state.guestbookAllmsg]
            })
            console.log(this.state.guestbookAllmsg);
            return;
        }
        alert("不能为空!")
    }
    isHave(){
        if(this.state.guestbookAllmsg.length==0){
            return <h2>暂无评论,快去评论吧~</h2>
        }
        let ok=this.state.guestbookAllmsg.map((msg)=>{
            return <li key={msg.gmsg}>评论者:{msg.gname}<br/>评论消息:{msg.gmsg}</li>; //jsx写法
        })
        return <ul>{ok}</ul>
    }
    render(){
        return(
            <div className='box'>
                <h1>留言板</h1>
                <input type="text" name='gname' onChange={this.formhadle} value={this.state.gname} placeholder="请输入评论人昵称" />
                <textarea onChange={this.formhadle} name='gmsg' value={this.state.gmsg} placeholder='评论消息'></textarea>
                <button onClick={this.addmsg}>发表</button>
                <div style={{'background':'pink'}}>{this.isHave()}</div>
            </div>
        )
    }
}
export default GuestBook

通过以上练习完美的进行总结~

组件传递

父传子

通过属性传值

子组件通过this.props.属性名接收

可以传多种类型值,为了省写代码,可对this.props进行解构

案例1
import React from "react";
/**
 * 父传子
 */
class Hello extends React.Component{
    constructor(props){
        //不传则是undefined
        super(props)
        console.log('构造方法',this.props);
    }

    render(){
        let {stname,age,hobby,fun,tag}=this.props;//解构
        return(
            <div>
                <h1>组件传参</h1>
                <p>字符串{this.props.stname}</p>
                <p>字符串2:{stname}年龄:{age+2}</p>
                <p>数组:{hobby}</p>
                <button onClick={fun}>点我触发传来的函数</button><br/>
                标签:{tag}
            </div>
        )
    }
}

export default Hello

index.js则需要引入Hello并且进行属性传值

<Hello stname='碰磕' age={18} hobby={['吃饭','睡觉','学习']} fun={()=>{alert('传过来的函数~')}} tag={<h1>我是传来的标签</h1>} /> 

案例2
//父传子通过属性传值...
class Parent1 extends Component{
    state={
        data:'碰磕'
    }
    render(){
        return(
            <div>
            <div>我是父组件</div>
            <Child baba={this.state.data}></Child>
            </div>
        )
    }
}
class Child extends Component{
    render(){
        return(
            <div>我是子组件:{this.props.baba}</div>
        )
    }
}
export default Parent1

子传父

父亲传递回调函数给子,子接收该函数并且调用它进行传值给父亲

//子传父
class Parent extends Component{
    state={
        gift:null
    }
    //回调函数
    callback=(obj)=>{
        console.log(`收到礼物:${obj}`);
        this.setState({
            gift:obj
        })
    }
    render(){
        let {gift} =this.state;
        return(
            <div>
                <h3>我的礼物:{gift}</h3>
                <hr/>
                <Child1 gifts={this.callback}></Child1>
            </div>
        )
    }
}

class Child1 extends Component{
    state={
        gift:'脑白金'
    }
    songgift=()=>{
        this.props.gifts(this.state.gift)   //调用父亲的函数并进行传值
    }
    render(){
        let {gift} =this.state;
        return(
            <div>
                <h3>我是子组件</h3>
                <button onClick={this.songgift}>向父亲送礼</button>
            </div>
        )
    }
}
export default Parent

兄弟传值(综合练习)

要求:儿子Tom给Jerry送礼

思路:Tom先给父亲,再由父亲转交给Jerry

import React, { Component } from "react";
//tom--->jerry         parent3(中转站)
class Parent3 extends Component{
    state={
        gift:null
    }
    callback=(opt)=>{
        console.log("收到给jerry的礼物",opt,"正在发送....");
        this.setState({
            gift:opt
        })
    }
    render(){
    return(
        <div>
        <Tom gifts={this.callback}></Tom>
        <hr/>
        <Jerry lw={this.state.gift}></Jerry>
        </div>
    )
    }
}
class Tom extends Component{
    state={
        gift:'滑板+溜冰鞋'
    }
    songli=()=>{
        this.props.gifts(this.state.gift)
    }
    render(){
        return(
            <div>
            <h1>Tom</h1>
            <button onClick={this.songli}>给Jerry送礼</button>
            </div>
        )
    }
}
class Jerry extends Component{
    render(){
        return(
            <div>
            <h1>Jerry</h1>
            <h2>收到Tom给我的礼物了:{this.props.lw}</h2>
            </div>
        )
    }
}
export default Parent3

组件之间的传值就完结了~忘了随时可查阅😊

组件生命周期

常用的三个:

  • 创建时:componentDidMount(): 发Ajax请求,DOM操作
  • 更新时:componentDidUpdate(): 接收Ajax请求,更新DOM操作
  • 卸载时:componentWillUnmount(): 在组件卸载及销毁之前直接调用,销毁操作

额外两个:

  • constructor():构造方法
  • render():数据渲染时执行

演示示例测试

执行顺序constructor()–>render()---->componentDidMount()

更新执行:componentDidUpdate()并且会进行先渲染render()再更新

卸载此处用子组件验证,销毁子组件时执行

/**
 * 创建时:componentDidMount(): 发Ajax请求,DOM操作
 * 更新时:componentDidUpdate(): 接收Ajax请求,更新DOM操作
 * 卸载时:componentWillUnmount(): 在组件卸载及销毁之前直接调用,销毁操作。
 */
import React, { Component } from "react";
class MyLife extends Component{
    state={
        num:1
    }
    constructor(){
        console.log("1....构造方法");
        super();
    }
    update=()=>{
        this.setState({
            num:this.state.num+1
        })
    }
    render(){   //数据渲染时执行
        console.log("2.....render进行渲染");
        return(
            <div>
                <h1>组件生命周期{this.state.num}</h1>
                <button onClick={this.update}>更新/攻击</button>
                {this.state.num>3 ? <span>英雄噶了</span>:<Hero life={this.state.num}></Hero>}
            </div>
        )
    }
    componentDidMount(){
        console.log("3.....组件挂载");
    }
    componentDidUpdate(){   //属性发生更新或者state发生更新触发
        console.log(".....组件更新");
    }
    
}
//子组件用于测试componentWillUnmount()卸载触发
class Hero extends Component{
    componentWillUnmount(){ //卸载触发
        console.log("....组件卸载");
    }
    render(){
        return <h3>英雄被攻击次数:{this.props.life}</h3>
    }
}
export default MyLife

路由

安装

npm install react-router-dom

引入

import {BrowserRouter as Router,Route,Link,Routes}from 'react-router-dom'

使用示例

  • 语法:
    • <Link to="路径">描述</Link>
    • <Routes><Route path="路径" element={<组件名 />}></Route></Routes>
import React,{Component} from 'react'
import {BrowserRouter as Router,Route,Link,Routes}from 'react-router-dom'   //(npm install react-router-dom)


const Main=()=><h3>我是首页哦</h3>
const Login=()=>(
    <div>
        <p>我是登录页面</p>
        <input type='text' />
        <button>登录</button>
    </div>
)
const App=()=>(
            <Router>
                <h1>路由测试</h1>
                <ul>
                    <li><Link to="/">首页</Link></li>
                    <li><Link to="/login">去登录</Link></li>
                    <li><Link to="/register">注册</Link></li>
                </ul>
                <Routes>
                <Route path="/login" element={<Login/>}></Route>
                <Route path="/" element={<Main/>}></Route>
                </Routes>
            </Router>
    )
    
export default App

在index.js入口文件导入使用即可

子路由

只需要在路由中返回一个子路由即可

示例

const Main=()=>{
    return (
        <div>
            <h3>我是首页哦</h3>
            <ul>
            <li><Link to="/register">注册</Link></li>
            </ul>
            <Routes>
            <Route path="/register"  exact element={<Register />} />
            </Routes>
        </div>
    )
}
const Register=()=>(
    <div>
        <p>我是注册页面</p>
        <input type='text' />
        <button>注册</button>
    </div>
)
const App=()=>(
            <Router>
                <h1>路由测试</h1>
                <ul>
                    <li><Link to="/main">首页</Link></li>
                </ul>
                <Routes>
                <Route path="/main" element={<Main/>}></Route>
                </Routes>
            </Router>
    )
    
export default App

和路由一样记得引入…

发Ajax请求(使用axios)

安装

npm install axios

导入

import axios from 'axios'   //导入axios(npm install axios

使用示例

此处用接口首页轮播图:https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata进行测试

最终响应到数据并赋值给info,循环显示在网页中

import React, { Component } from 'react'
import axios from 'axios'   //导入axios(npm install axios)

class Apps extends Component{
    state={
        info:[]
    }
    handle=async ()=>{
        let url="https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"
        let ret=await axios.get(url);
        this.setState({
            info:ret.data.message
        })
    }
    render(){
        return(
            <div>
                <h3>测试Axios请求</h3>
                <button onClick={this.handle}>发Ajax请求</button>
                {
                    this.state.info.map((item)=>{
                        return(
                        <p key={item.goods_id}>
                            <span>{item.goods_id}</span>
                            <img width="100px" src={item.image_src} />
                        </p>
                        )
                    })

                }
            </div>
        )
    }
}
export default Apps

完结撒花🌼~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碰磕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值