您的位置:首页 > 文旅 > 旅游 > 什么是网络营销报价_郑州建站以来_慈溪seo排名_如何注册百度账号

什么是网络营销报价_郑州建站以来_慈溪seo排名_如何注册百度账号

2024/10/9 21:27:15 来源:https://blog.csdn.net/weixin_46191445/article/details/142712001  浏览:    关键词:什么是网络营销报价_郑州建站以来_慈溪seo排名_如何注册百度账号
什么是网络营销报价_郑州建站以来_慈溪seo排名_如何注册百度账号

React介绍

React由Meta公司开发,是一个用于构建Web和原生交互界面的库

React的优势

相较于传统基于DOM开发的优势

  1. 组件化的开发方式
  2. 不错的性能

相较于其它前端框架的优势

  1. 丰富的生态
  2. 跨平台支持

开发环境创建

create-react-app是一个快速创建React开发环境的工具,底层由Webpack构件,封装了配置细节,开箱即用
执行命令:

npx create-react-app react-basic
  1. npx - Node.js工具命令,查找并执行后续的包命令
  2. create-react-app - 核心包(固定写法),用于创建React项目
  3. react-basic React项目的名称(可以自定义)
    启动项目 npm start

渲染流程:App.js跟组件导入到index.js里,把根组件渲染到id为root的index.html

JSX基础

什么是JSX

JSX是JavaScript和XMl(HTML)的缩写,表示在JS代码中编写HTML模版结构,它是React中构建UI的方式

const message = 'this is message'
function App(){return (<div><h1>this is title</h1>{message}</div>)
}

优势:

  1. HTML的声明式模版写法
  2. JavaScript的可编程能力

JSX高频场景-JS表达式

在JSX中可以通过 大括号语法{} 识别JavaScript中的表达式,比如常见的变量、函数调用、方法调用等等

  1. 使用引号传递字符串

  2. 使用JS变量

  3. 函数调用和方法调用

  4. 使用JavaScript对象

注意:if语句、switch语句、变量声明不属于表达式,不能出现在{}中

const message = 'this is message'
function getAge(){return 18
}
function App(){return (<div><h1>this is title</h1>{/* 字符串识别 */}{'this is str'}{/* 变量识别 */}{message}{/* 函数调用 渲染为函数的返回值 */}{getAge()}</div>)
}

JSX高频场景-列表渲染

在JSX中可以使用原生js种的map方法 实现列表渲染

key的作用:React框架内部使用,提升更新性能的

const list = [{id:1001, name:'Vue'},{id:1002, name: 'React'},{id:1003, name: 'Angular'}
]
function App() {return (<div className="App">this is App{/* 渲染列表 */}{/* map循环哪个结构,return哪个结构 */}<ul>{list.map(item => <li key={item.id}> {item.name} </li>)}</ul></div>)
}

JSX高频场景-条件渲染

在React中,可以通过逻辑与运算符&&、三元表达式(?😃 实现基础的条件渲染

const flag = true
const loading = false
function App(){return (<div>{flag && <span>this is span</span>}{loading ? <span>loading...</span>:<span>this is span</span>}</div>)
}

JSX高频场景-复杂条件渲染

解决方案:自定义函数 + 判断语句

const type = 1  // 0|1|3function getArticleJSX(){if(type === 0){return <div>无图模式模版</div>}else if(type === 1){return <div>单图模式模版</div>}else(type === 3){return <div>三图模式模版</div>}
}
function App(){return (<div>{ getArticleJSX() }</div>)
}

React的事件绑定

基础实现

React中的事件绑定,通过语法 on + 事件名称 = { 事件处理程序 },整体上遵循驼峰命名法

function App(){const clickHandler = ()=>{console.log('button按钮点击了')}return (<button onClick={clickHandler}>click me</button>)
}

使用事件参数

在事件回调函数中设置形参e即可

function App(){const clickHandler = (e)=>{console.log('button按钮点击了', e)}return (<button onClick={clickHandler}>click me</button>)
}

传递自定义参数

语法:事件绑定的位置改造成箭头函数的写法,在执行clickHandler实际处理业务函数的时候传递实参

function App(){const clickHandler = (name)=>{console.log('button按钮点击了', name)}return (<button onClick={()=>clickHandler('jack')}>click me</button>)
}

注意:不能直接写函数调用,这里事件绑定需要一个函数引用

同时传递事件对象和自定义参数

语法:在事件绑定的位置传递事件实参e和自定义参数,clickHandler中声明形参,注意顺序对应

function App(){const clickHandler = (name,e)=>{console.log('button按钮点击了', name,e)}return (<button onClick={(e)=>clickHandler('jack',e)}>click me</button>)
}

React组件基础使用

一个组件就是一个用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以服用多次

组件基础使用

在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI, 渲染组件只需要把组件当成标签书写即可

// 1. 定义组件
function Button(){return <button>click me</button>
}
// 2. 使用组件
function App(){return (<div>{/*方式1: 自闭和 */}<Button/>{/*方式2: 成对标签 */}<Button></Button></div>)
}

组件状态管理-useState

基础使用

1.useState 是一个 React Hook(函数),返回值是一个数组

2.数组中第一个参数是状态变量,第二个参数是set函数用来修改状态变量

3.useState参数将作为count的初始值

和普通JS变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图)

import {useState} from 'react'
function App() {const [ count, setCount ] = useState(0)return (<div className="App"><button onClick={()=>setCount(count+1)}>{ count }</button></div>);
}

状态的修改规则

在React中状态被认为是只读的,我们应该始终替换它而不是修改它, 直接修改状态不能引发视图更新

修改对象状态

对于对象类型的状态变量,应该始终给set方法一个全新的对象 来进行修改

import {useState} from 'react'
function App() {const [form,setForm] = useState({name:'jack'})const changeForm = ()=>{//错误写法:直接修改 form.name = 'john'//正确写法setForm({...form,name:'apple'})}return (<div className="App"><button onClick={changeForm}>{ form.name }</button></div>);
}
export default App;

组件的基础样式处理

React组件基础的样式控制有俩种方式,行内样式和class类名控制

<div style={{ color:'red'}}>this is div</div>
.foo{       //index.css的内容color: red;
}
import './index.css'    //导入css文件
function App(){return (<div><span className="foo">this is span</span></div>)
}

B站评论案例

  1. 渲染评论列表
  2. 删除评论实现
    1. 删除显示------条件渲染
    2. 删除功能------拿到当前项id以id为条件对评论列表做filter过滤
  3. 渲染导航Tab和高亮实现
  4. 评论列表排序功能实现

完成版本

 import { useState } from 'react'
import './App.scss'
import avatar from './images/bozai.png'
import orderBy from 'lodash/orderBy'/*** 评论列表的渲染和操作** 1. 根据状态渲染评论列表* 2. 删除评论*/// 评论列表数据
const defaultList = [{// 评论idrpid: 3,// 用户信息user: {uid: '13258165',avatar: '',uname: '周杰伦',},// 评论内容content: '哎哟,不错哦',// 评论时间ctime: '10-18 08:15',like: 88,},{rpid: 2,user: {uid: '36080105',avatar: '',uname: '许嵩',},content: '我寻你千百度 日出到迟暮',ctime: '11-13 11:29',like: 88,},{rpid: 1,user: {uid: '30009257',avatar,uname: '黑马前端',},content: '学前端就来黑马',ctime: '10-19 09:00',like: 66,},
]
// 当前登录用户信息
const user = {// 用户iduid: '30009257',// 用户头像avatar,// 用户昵称uname: '黑马前端',
}/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序*  最热 => 喜欢数量降序*  最新 => 创建时间降序*/// 导航 Tab 数组
const tabs = [{ type: 'hot', text: '最热' },{ type: 'time', text: '最新' },
]const App = () => {// 导航 Tab 高亮的状态const [activeTab, setActiveTab] = useState('hot')const [list, setList] = useState(defaultList)// 删除评论const onDelete = rpid => {// 如果要删除数组中的元素,需要调用 filter 方法,并且一定要调用 setList 才能更新状态setList(list.filter(item => item.rpid !== rpid))}// tab 高亮切换const onToggle = type => {setActiveTab(type)let newListif (type === 'time') {// 按照时间降序排序// orderBy(对谁进行排序, 按照谁来排, 顺序)newList = orderBy(list, 'ctime', 'desc')} else {// 按照喜欢数量降序排序newList = orderBy(list, 'like', 'desc')}setList(newList)}return (<div className="app">{/* 导航 Tab */}<div className="reply-navigation"><ul className="nav-bar"><li className="nav-title"><span className="nav-title-text">评论</span>{/* 评论数量 */}<span className="total-reply">{list.length}</span></li><li className="nav-sort">{/* 高亮类名: active */}{tabs.map(item => {return (<divkey={item.type}className={item.type === activeTab ? 'nav-item active' : 'nav-item'}onClick={() => onToggle(item.type)}>{item.text}</div>)})}</li></ul></div><div className="reply-wrap">{/* 发表评论 */}<div className="box-normal">{/* 当前用户头像 */}<div className="reply-box-avatar"><div className="bili-avatar"><img className="bili-avatar-img" src={avatar} alt="用户头像" /></div></div><div className="reply-box-wrap">{/* 评论框 */}<textareaclassName="reply-box-textarea"placeholder="发一条友善的评论"/>{/* 发布按钮 */}<div className="reply-box-send"><div className="send-text">发布</div></div></div></div>{/* 评论列表 */}<div className="reply-list">{/* 评论项 */}{list.map(item => {return (<div key={item.rpid} className="reply-item">{/* 头像 */}<div className="root-reply-avatar"><div className="bili-avatar"><imgclassName="bili-avatar-img"src={item.user.avatar}alt=""/></div></div><div className="content-wrap">{/* 用户名 */}<div className="user-info"><div className="user-name">{item.user.uname}</div></div>{/* 评论内容 */}<div className="root-reply"><span className="reply-content">{item.content}</span><div className="reply-info">{/* 评论时间 */}<span className="reply-time">{item.ctime}</span>{/* 评论数量 */}<span className="reply-time">点赞数:{item.like}</span>{user.uid === item.user.uid && (<spanclassName="delete-btn"onClick={() => onDelete(item.rpid)}>删除</span>)}</div></div></div></div>)})}</div></div></div>)
}export default App

React表单控制

受控绑定

概念:用React组件的状态(useState)控制input表单的状态

React(state) -----> state绑定到input 的value属性 -----> input(value)

React(state)<----- 把input最新的value值设置给state <----- value

//通过value属性绑定react状态
//绑定onchange事件,通过事件参数e拿到输入框最新的值,反向修改到react状态
function App(){const [value, setValue] = useState('')return (<input type="text" value={value} onChange={e => setValue(e.target.value)}/>)
}

获取DOM(非受控绑定)

  1. useRef生成ref对象,绑定到dom标签身上
  2. dom可用时,ref.current获取dom (渲染完毕之后 dom生成之后才能用)
import { useRef } from 'react';
function App() {const inputRef = useRef(null)const showDom = ()=> {console.dir(inputRef.current)}return (<div className="App"><input type="text" ref={inputRef}/>   //绑定到dom标签身上<button onClick={showDom}> 获取DOM</button></div>);
}
export default App;
}

时间格式修改

npm install dayjs  //插件安装
import dayjs from 'dayjs';
function App() {const showDom = ()=> {console.log(dayjs(new Date()).format('MM-DD hh:mm'));}

组件通信

父子通信-父传子

**实现步骤 **

  1. 父组件传递数据 - 在子组件标签上绑定属性
  2. 子组件接收数据 - 子组件通过props参数接收数据

props:是一个对象,里面包含了父组件传递过来的所有数据

function Son(props){return <div>{ props.name }</div>
}
function App(){const name = 'this is app name'return (<div><Son name={name}/>  //父组件中使用子组件</div>)
}

特殊的prop-chilren

场景:当我们把内容嵌套在组件的标签内部时,组件会自动在名为children的prop属性中接收该内容

function Son(props){console.log(props)return <div> {props.children}</div>
}
function App() {]return (<div><Son><span>this is span</span></Son></div>)
}
export default App;

父子通信-子传父

核心思路:在子组件中调用父组件中的函数并传递实参

function Son({ onGetMsg }){ //解构const sonMsg = 'this is son msg'return (<div>{/* 在子组件中执行父组件传递过来的函数 */}<button onClick={()=>onGetMsg(sonMsg)}>send</button></div>)
}
function App(){const getMsg = (msg)=>console.log(msg)return (<div>{/* 传递父组件中的函数到子组件 */}<Son onGetMsg={ getMsg }/></div>)
}

兄弟组件通信

实现思路: 借助 状态提升 机制,通过共同的父组件进行兄弟之间的数据传递

  1. A组件先通过子传父的方式把数据传递给父组件App A —> App
  2. App拿到数据之后通过父传子的方式再传递给B组件 App —> B
// 1. 通过子传父 A -> App
// 2. 通过父传子 App -> Bimport { useState } from "react"function A ({ onGetAName }) {// Son组件中的数据const name = 'this is A name'return (<div>this is A compnent,<button onClick={() => onGetAName(name)}>send</button></div>)
}function B ({ name }) {return (<div>this is B compnent,{name}</div>)
}function App () {const [name, setName] = useState('')const getAName = (name) => {setName(name)}return (<div>this is App<A onGetAName={getAName} /><B name={name} /></div>)
}export default App

context跨层组件通信

比如一个层级关系为APP(A(B)) ,想实现APP—>B 的通信

实现步骤:

  1. 使用 createContext方法创建一个上下文对象Ctx
  2. 在顶层组件(App)中通过 Ctx.Provider 组件提供数据
  3. 在底层组件(B)中通过 useContext 钩子函数获取消费数据
// App -> A -> Bimport { createContext, useContext } from "react"// 1. createContext方法创建一个上下文对象const MsgContext = createContext()function A () {return (<div>this is A component<B /></div>)
}function B () {// 3. 在底层组件 通过useContext钩子函数使用数据const msg = useContext(MsgContext)return (<div>this is B compnent,{msg}</div>)
}function App () {const msg = 'this is app msg'return (<div>{/* 2. 在顶层组件 通过Provider组件提供数据 */}<MsgContext.Provider value={msg}>this is App<A /></MsgContext.Provider></div>)
}export default App

React副作用管理-useEffect

useEffect是一个React Hook函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAX请求,更改DOM等等

基础使用

需求:在组件渲染完毕之后,立刻从服务端获取平道列表数据并显示到页面中

useEffect(() => { }  ,  [ ])

说明:

  1. 参数1是一个函数,可以把它叫做副作用函数,在函数内部可以放置要执行的操作

  2. 参数2是一个数组(可选参),依赖项数组,不同依赖项会影响第一个参数函数的执行,当是一个空数组的时候,副作用函数只会在组件渲染完毕之后执行一次

    接口地址:http://geek.itheima.net/v1_0/channels

useEffect依赖说明

useEffect副作用函数的执行时机存在多种情况,根据传入依赖项的不同,会有不同的执行表现

依赖项副作用功函数的执行时机
没有依赖项组件初始渲染执行一次 + 任意组件更新时执行
空数组依赖只在初始渲染时执行一次
添加特定依赖项组件初始渲染 + 依赖项变化时执行

清除副作用

概念:在useEffect中编写的由渲染本身引起的对接组件外部的操作,社区也经常把它叫做副作用操作,比如在useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清理副作用

说明:清除副作用的函数最常见的执行时机是在组件卸载时自动执行

useEffect(()=> {//实现副作用操作逻辑return()=>{//清除副作用逻辑}
},[])
//例子:在Son组件渲染时开启一个定时器,卸载时清除这个定时器
import { useEffect, useState } from "react"
function Son () {// 1. 渲染时开启一个定时器useEffect(() => {const timer = setInterval(() => {console.log('定时器执行中...')}, 1000)return () => {// 清除副作用(组件卸载时)clearInterval(timer)}}, [])return <div>this is son</div>
}
function App () {// 通过条件渲染模拟组件卸载const [show, setShow] = useState(true)return (<div>{show && <Son />} //条件渲染<button onClick={() => setShow(false)}>卸载Son组件</button></div>)
}export default App

自定义Hook实现

概念:自定义Hook是以 use打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用

// 封装自定义Hook// 问题: 布尔切换的逻辑 当前组件耦合在一起的 不方便复用// 解决思路: 自定义hookimport { useState } from "react"function useToggle () {// 可复用的逻辑代码const [value, setValue] = useState(true)const toggle = () => setValue(!value)// 哪些状态和回调函数需要在其他组件中使用 returnreturn {value,toggle}
}// 封装自定义hook通用思路// 1. 声明一个以use打头的函数
// 2. 在函数体内封装可复用的逻辑(只要是可复用的逻辑)
// 3. 把组件中用到的状态或者回调return出去(以对象或者数组)
// 4. 在哪个组件中要用到这个逻辑,就执行这个函数,解构出来状态和回调进行使用function App () {const { value, toggle } = useToggle()return (<div>{value && <div>this is div</div>}<button onClick={toggle}>toggle</button></div>)
}export default App

React Hooks使用规则

  1. 只能在组件中或者其他自定义Hook函数中调用
  2. 只能在组件的顶层调用,不能嵌套在if、for、其它的函数中

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com