临沂做商城网站建设,wordpress会员无法注册,做企业门户网站要准备哪些内容,建设网站的群相关参考
react
首先#xff0c;我们先大概了解一下什么是react以及react可以干什么。 React 是 Facebook 开源的一个用于构建用户界面的一款 JavaScript 库#xff0c;主要用于构建 UI。
react的特点
声明式编程 react使用jsx进行渲染#xff0c;这是一种类似html的语法…相关参考
react
首先我们先大概了解一下什么是react以及react可以干什么。 React 是 Facebook 开源的一个用于构建用户界面的一款 JavaScript 库主要用于构建 UI。
react的特点
声明式编程 react使用jsx进行渲染这是一种类似html的语法可以通过定义属性来描述要呈现的内容。组件化react将应用程序分解为组件每个组件都是一个独立的模块可以独立的开发和测试组件可以包含状态、属性、事件处理等程序。并且可以互相通信和交互。状态管理 react提供了一个状态管理库Redux,用于管理应用程序的装填。Redux将应用程序的状态存储在单个状态树种并提供了各种操作来修改状态虚拟dom react使用虚拟dom来跟踪应用程序状态而不是实际DOM,这使得react能够快速响应用户输入并且可以更高效的渲染社区支持 react拥有庞大的社区支持有许多可用的插件、库和工具快速帮助开发人员构建和优化应用程序
基于组件页面中部分内容 学习一次 随处使用 react-native
安装react 创建功能react 核心库 react-dom dom相关功能渲染功能
常见组件
以下是常见的React组件
ReactDOM.render()用于将React组件渲染到DOM中。ReactDOM.createPortal()用于创建一个将子组件渲染到指定容器中的React组件。ReactDOM.Fragment()用于将多个React元素包装在一个不可展开的元素中。ReactDOM.StrictMode()用于启用React的严格模式使React在渲染过程中更严格地检查组件的依赖关系。ReactDOM.createContext()用于创建一个上下文Context对象可以在组件中使用该上下文对象来获取共享的状态和数据。ReactDOM.useContext()用于在组件中使用上下文对象来获取共享的状态和数据。ReactDOM.useState()用于在组件中定义状态state并更新状态。ReactDOM.useEffect()用于在组件中定义副作用side effects并更新状态。ReactDOM.useReducer()用于在组件中定义一个reducer函数该函数将处理状态更新的逻辑。ReactDOM.useCallback()用于在组件中定义一个回调函数该函数将在组件第一次渲染时被调用并返回一个缓存的函数以避免每次渲染时都重新计算。ReactDOM.useMemo()用于在组件中定义一个memoized函数该函数将在第一次调用时计算结果并在之后的调用中缓存结果以避免重复计算。ReactDOM.useDebugValue()用于在调试时向React堆栈中添加调试信息。ReactDOM.createRef()用于创建一个引用ref可以在组件中使用该引用来访问其DOM元素或子组件。ReactDOM.forwardRef()用于将一个React组件转发给另一个React组件以使其可以访问父组件的props和refs。ReactDOM.memo()用于创建一个memoized函数该函数将在第一次调用时计算结果并在之后的调用中缓存结果以避免重复计算。
箭头函数
在es6之后出现了一种函数叫箭头函数它比普通函数更加简洁方便。我们来举一个简单的例子
//普通函数
const addfunction (a,b){return ab
}//箭头函数
const addNew(a,b){return ab
}箭头函数的特性
那么箭头函数和普通函数相比有哪些特性呢我们来看看
箭头函数没有this当访问this的时候会获取外部的this箭头函数没有自己的 arguments 对象箭头函数不能用作构造函数当使用 new 调用时会出错。它们也没有 prototype 属性。箭头函数作为表达式的时候 的优先级低于大多数运算符
npm
在了解react之前我们还需要了解一些基础工具比如npmnpm 全称是 node package manager,其实就是一个管理js编写的软件包的管理工具可以下载安装升级上传js软件包。 node.js内置了npm所以只要安装了node.js就可以使用npm。node.js的安装非常简单官方地址下载就可以安装了。安装完毕后使用npm install npmlatest -g命令将npm升级到最新版本。
npm镜像源配置
为了在国内尽快的下载js库我们需要配置一下npm的镜像源即从哪个源下载这里我指定了华为其他的还有腾讯淘宝等镜像源。
npm config set registry https://mirrors.huaweicloud.com/repository/npm/npm配置解读
我们可以通过npm config list查看npm的相关配置项
$ npm config list
; builtin config from /usr/local/lib/node_modules/npm/npmrc
prefix /usr/local
; user config from /Users/zhangguofu/.npmrc
registry https://mirrors.huaweicloud.com/repository/npm/
; node bin location /usr/local/Cellar/node/21.5.0/bin/node
; node version v21.5.0
; npm local prefix /Users/zhangguofu/website/react
; npm version 10.2.4
; Run npm config ls -l to show all defaults.prefix指定npm的安装路径。registry设置JavaScript库的镜像源。在这个例子中设置为https://mirrors.huaweicloud.com/repository/npm/。node bin location指定Node.js二进制文件的位置。node version表示已安装的Node.js版本。npm local prefix指定npm的本地安装路径。即我下载的js组件的位置npm version表示已安装的npm版本。
react的安装
接下来我们就开始讲react的安装
npm安装
我们前面安装了npm下面我们通过npm来下载react我执行命令npm i react react-dom那么在我的npm local prefix路径下就会生成一个node_modules的目录。注意这里面react.js可以说是我们的核心文件用来执行业务逻辑和数据但是数据完成之后还是要需要渲染成dom才能被用户看到那么这些数据怎么样才能转换成真正的domn呢这就用到了react-dom。
hello react 接下来我用一段简单的代码先来演示一下react
body
div idroot/div
/body
!--引入react.js--
script src../node_modules/react/umd/react.development.js/script
!--引入react-dom.js--
script src../node_modules/react-dom/umd/react-dom.development.js/script
script//这个方法需要三个参数 type prop childrenconst title React.createElement(div,null,hello world)// 渲染到root里面ReactDOM.render(title,document.getElementById(root));
/script脚手架安装
我们知道脚手架是开发现代web应用的必备比如webpack babel eslint等工具辅助项目开发为了让我们更专注的开发业务减少配置项目我们使用脚手架来安装和使用react
执行命令npx create-react-app my-app即可创建一个my-app的目录其中npx是npm5.2版本中的一个命令create-react-app是脚手架的名字。my-app 就是我们的项目了。
$ ls
README.md node_modules package-lock.json package.json public src我们进入项目目录并执行npm start即可启动项目默认是3000端口,接下来我们只需使用三行代码就可以实现一个hello react
//导入文件
import React from react
import ReactDOM from react-dom
ReactDOM.render(divhello react /div,document.getElementById(root))JSX
我们在上面代码可以看到在js里面我们竟然可以直接写html而且还不报错其实这个有趣的标签语法既不是字符串也不是 HTML而是JSX它是一个 JavaScript 的语法扩展。我们建议在 React 中配合使用 JSXJSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模板语言但它具有 JavaScript 的全部功能。 那我们可能会很奇怪为什么js里面的写JSX不会报错呢其实这就是脚手架的功劳脚手架已经帮我们下载安装了三个包
babel/clibabel/corebabel/preset-react 这个babel包负责将JSX编译为react可执行的文本举个例子const h1 h1this is a H1 Tag/h1经过编译后会变成const h1 React.createElement(h1, null, this is a H1 Tag);接下来我们看看JSX的功能。
一般使用
//导入文件
import React from react
import ReactDOM from react-dom
// 注意 dom的属性命名必须是小驼峰 整个jsx推荐用小括号包裹 dom如果没有子节点,可以省略闭合标签
const content(div classNamecontenthello react span/ /div)
ReactDOM.render(content,document.getElementById(root))我们来对比一下渲染后的dom
div idrootdiv classcontenthello react span/span /div/divjs变量的嵌入
const myName张三
const content(div classNamecontent{myName}/div)三元表达式
const age19
const content(div classNamecontentli是否成年:{age18?成年:未成年}/li/div
)函数表达式
const func(){return divi am a function/div
}
const contenth1{func()}/h1条件和逻辑运算符
const age20
const func(){//逻辑运算return age 18 divi am a function/div
}const func2(){if (age18){return divi am {age}/div}
}
const contenth1{func()}{func2()}/h1列表渲染
const heros[{name:batman,id:20},{name:x-police,id:21},
]
const contenth1{heros.map(itemli key{item.id}{item.name}/li)}/h1引入css文件
可以通过类名或者行内样式写样式
import ./css/index.css
const contentdivh1 style{{color:red}}i am h1/h1h2 classNametag2i am h2/h2
/divreact的组件
组件是react的一等公民你的每一个业务可能都是多个组件拼装起来的。每个组件可能代表一个功能。组件实现了代码之间的独立性复用性和耦合性。 组件有两种实现方式一种是以函数形式实现一种是以class的形式实现。
函数创建组件
接下来我们看一下函数实现的组件长什么样子,其中我们要注意函数的名称必须大写为什么我们写普通的jsx可能会有div ul 这些那么babel如何知道你写的这个是普通的jsx还是组件就是看第一个字母是否大写另一方面组件必须有返回值也可以返回null
function GetName() {return divi am x/div
}
const contentGetName/箭头函数创建组件 这里遇到一个小插曲浏览器一直报Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if its running React 17,这里我们一下改一下rendder的方式
//导入文件
import React from react
import ReactDOM from react-dom/client
import ./css/index.css
const GetName() {return divi am x/div
}
const contentGetName/
const root ReactDOM.createRoot(document.getElementById(root))
root.render(content)类创建组件
其实对于一个后端人员来说class对我们来说实在太熟西了。但是这里需要有两个地方注意一个是class必须继承自父类React.Component,第二是必须提供render方法且该方法必须有返回值我们举例看一下
class Hello extends React.Component{render() {return divi am class hello/div}
}
const contentHello/那么我们也看到了既然可以使用class创建组件那么我们不可能将很多个class堆在一个js文件中下面我们看怎么组件抽离
组件抽离
组件抽离其实很简单就是注意两点一是js文件中导入react库第二是导出即可export我们新建一个hello.js的文件,
import React from react;
class Hello extends React.Component {render(){return divi am hello /div}
}
//导出组件
export default Hello;文件中引入
import Hello from ./Hello
const contentHello/react事件处理
我们知道在js里面有很多事件 那么react里面是怎么绑定事件的呢其实和js很像就是这样的形式on事件名称{(){}}但是注意一点事件名称必须是驼峰命名比如我们绑定一个点击事件
class Hello extends React.Component {Haha(){alert(haha);}render(){return button onClick{this.Haha}i am hello /button}
}合成事件
事件可以通过合成事件进行实例传递比如我们想调用浏览器原生事件因为原生事件对所有浏览器都是兼容的。那么我们怎么使用这些原生事件呢我们举个例子
class Hello extends React.Component {Haha(e){//禁止跳转e.preventDefault();}render(){return a hrefhttps://www.acurd.com onClick{this.Haha}i am hello /a}
}state
我们前面说过react是有状态管理的通过state和setState来配合完成但是函数组件是没有状态的。而类组件才有状态为什么很简单因为class里面可以定义自己的属性修改状态是通过this指向。函数明显不能实现这些功能。比如我们现在来定义一个
class Hello extends React.Component {//利用构造函数完成state初始化// constructor(props){// super(props);// this.state{// name:x,// age:18// }// }//简洁化state初始化state{name:x,age:18}render() {return (ulliname:{this.state.name}/liliage:{this.state.age}/li/ul)}
}
}我们怎么让数据动起来呢这里就用到了setState方法,注意setState里面是一个对象想要修改哪个属性就修改哪个属性。 render() {return (ulliname:{this.state.name}/liliage:{this.state.age}/libutton onClick{(){this.setState({age:this.state.age1})}}点我加一岁/button/ul)}那么我们能否把 onClick方法提出来呢这个当然是可以的我们前面就做过了如果我们做一写业务逻辑处理自然是没有问题但是如果想要改state就得先绑定state,我们来看看 ChangeAge(){this.setState({age:this.state.age1})}render() {return (ulliname:{this.state.name}/liliage:{this.state.age}/libutton onClick{this.ChangeAge}点我加一岁/button/ul)}呃报错了Uncaught TypeError: Cannot read properties of undefined (reading setState)这个this可不是onClick的this而是 this.setState的this,为啥函数内部的this是undefined其实这是babel编译后的结果babel是在use strict模式下编译的不允许this指向函数以外的对象那么this只能指向undefined。
this的指向问题
好了我们说了函数内部的this是undefined也解释了原因那么我们怎么使用到外部的this呢。
利用箭头函数去找外面的this render() {return (ulliname:{this.state.name}/liliage:{this.state.age}/libutton onClick{()this.ChangeAge()}点我加一岁/button/ul)}或者我们直接把函数定义为箭头函数 ChangeAge(){this.setState({age:this.state.age1})}第二种方法就是在构造函数中将class的this绑定到函数的this上面 //利用构造函数完成state初始化constructor(props){super(props);this.state{name:x,age:18}this.ChangeAgethis.ChangeAge.bind(this)}props
props是什么东西它类似于你在声明对象的时候给对象添加的属性,它具有以下特性
传递数据props可以用于向子组件传递数据这些数据可能是父组件的状态也可能是其他兄弟组件的状态。子组件获取到数据更新自己的状态外部控制通过props,父组件可以对子组件进行控制例如设置初始状态或者传递回调函数这种控制方式让react组件之间可以具有更好的互动性和协作性。属性约束props是只读的子组件不能修改父组件传过来的数据。
我们举个例子看一下
const contentHello name张三 age18 /那么我们在使用的使用只需要读取到就行了 ulliname:{this.props.name}/liliage:{this.props.age}/li/ul或者一次性从props里面取出来 render() {const {name,age} this.propsreturn (ulliname:{name}/liliage:{age}/li/ul)}展开运算符的用法
//展开符
const arr[1,2,3,4,5,6,7,8,9,10]
const arr2[11,21,13]
console.log(...arr);
//合并数组
let arr3[...arr,...arr2]
console.log(arr3);
//展开对象
let obj{name:张三,age:18,sex:男
}
//展开对象需要用花括号表示对象
console.log({...obj});
//给对象添加属性
let obj2{...obj,addr:xxxx}
console.log(obj2);既然对象可以展开那么我们就可以利用展开符批量添加props
let p{name:张三1,age:182,sex:男
}
const contentHello {...p} /Helloprops限制 我们还可以对props进行限制比如类型是否必填等追忆这种方式对class 和函数都是适用的
//对类型进行限制
Hello.propTypes{name:PropTypes.string.isRequired,sex:PropTypes.string.isRequired,age:PropTypes.number.isRequired,speak:PropTypes.func.isRequired
}
//初始默认值
Hello.defaultProps{name:张三,sex:男,age:18
}props的简写方式 我们也可以以对象的属性的形式来限制比如下面这种写在类的里面这对我们后端程序员来说就熟悉的多了 static propTypes {name:PropTypes.string,age:PropTypes.number,sex:PropTypes.string}static defaultProps{name:李四,sex:女,age:20}函数中怎么使用props
function Speak(props){let {age, name, sex}propsreturn (divulliage:{age}/liliname:{name}/lilisex:{sex}/li/ul/div)
}
Speak.propTypes{age:PropTypes.number,name:PropTypes.string,sex:PropTypes.string
}const contentSpeak {...p} /Speakrefs与事件处理
组件内的标签可以通过ref打标识react就是通过ref识别到对应的元素来完成对元素的操作。
class Hello extends React.Component {Msg(){//input1 就是refinput1指定的那个domlet msgthis.refs.input2.value;alert(msg);}render() {return (ulliinput typetext refinput1 placeholder输入数据//liliinput typetext refinput2 placeholder输入数据//libutton onClick{this.Msg} 点击提示数据/button/ul)}
}但是上面的ref的值其实是一个字符串字符串效率不高第二方面不方便识别可能在使用中不小心使用错误。接下来我们看使用回调怎么使用这种写法相当于通过回调函数给class赋值了一个属性。 Msg(){alert(this.input1.value)}render() {return (ulliinput typetext ref{(dom){this.input1dom}} placeholder输入数据//libutton onClick{this.Msg} 点击提示数据/button/ul)}当然了能用箭头函数内嵌的我们肯定可以提到外面来使用e就是当前dom对象 setInput(e){this.input1e}但是这种回调似乎没有字符串写起来方便啊怎么办react又做了更新既然原来你是在直接声明了字符串容易出问题那么这样我先让你声明ref,让后你只需要像使用字符串一样把你声明的ref赋值给ref就可以了。比如下面 input1React.createRef()Msg(){alert(this.input1.current.value)}如果发生事件的元素恰好就是我们要操作的元素我们就可以使用对象e作为参数来处理比如下面
class Hello extends React.Component {Msg (e) {alert(e.target.value)}render() {return (liinput onBlur{this.Msg} typetext ref{this.input1} placeholder输入数据//li)}
}class中的constructor函数的使用场景
通过this.state初始化内部的state为时间处理函数绑定实例
事件处理
通过on属性指定事件处理函数合成事件是为了更好的兼容委托给了最外层的元素比如div 为了高效通过event.target活得到dom对象。
收集表单数据
非受控组件 所有输入类的dom 如果是现用现取则属于非受控组件。主动获取值受控组件 由事件去驱动修改状态或者数据这些就是受控组件
高阶函数
高阶函数如果函数接收或者返回值有一个是函数类型那么该函数是高阶函数。 比如这种用户名: input onChange{this.setData} typetext/,其实就是onChange这个事件执行了setData()的这个方法返回了一个操作指令所以如果你传了参数必须返回一个函数给onChange setData(dataType){return (e){this.setState({[dataType]:e.target.value})}}getData(e){e.preventDefault()let {name,pwd}this.stateconsole.log(name,pwd)}render() {return (form onSubmit{this.getData}用户名: input onChange{this.setData(name)} typetext/pwd: input onChange{this.setData(pwd)} typetext/button提交/button/form)}函数的柯里化继续通过调用高阶函数的返回的函数实现多次接收参数最后统一处理函数的编码方式。其实就是一次调用多个函数将一组数据通过多个函数的处理而得到结果
let sum (a) {return (b) {return (c) {return a b c}}
}
console.log(sum(1)(2)(3));相关参考
官方文档 技术栈为React Hook React-router-v6 Mobx AntD
尚硅谷react分章
尚硅谷React 源码地址https://gitee.com/react-cp/react-pc-code React基础讲义: https://www.yuque.com/fechaichai/qeamqf/xbai87 React和Mobx讲义: https://www.yuque.com/fechaichai/qeamqf/apomum ReactPc项目讲义: https://www.yuque.com/fechaichai/tzzlh1