技术标签: 前端 react 前端框架之 —— React javascript 软件框架
目录
React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。
详细教程可参见官网:
React 官方中文文档 – 用于构建用户界面的 JavaScript 库https://react.docschina.org/
React框架的书写方式分为两种,一种是脚本方式(JavaScript标签引入,练习使用);一种是react脚手架方式(常用)。
为了能够正常使用react框架进行编程,我们创建好自己的项目之后,需要在页面中引入两个CDN链接:react库 和 react-dom库;
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
对于这两个远程地址也可直接在官网下载到本地之后直接用<script src=""></script>引入项目中;如下:
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
除此之外还应注意,React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,比如,在 UI 中需要绑定处理事件、在某些时刻状态发生变化时需要通知到 UI,以及需要在 UI 中展示准备好的数据。所以在React中使用的是JSX语法,但是浏览器不识别JSX,我们就需要引入babel(Babel 中文网 · Babel - 下一代 JavaScript 语法的编译器)来解析翻译,而且需要在script写上对应属性,格式如下:
//引入Babel
<script src="./babel.min.js"></script>
<script type="text/babel">
//内容
</script>
引入所需要的链接之后,就需要创建挂载点(其实就是一个带有id名的div)了,专门用于插入后续生成的内容,如下:
<div id="root"></div>
这样,一个完整的react初始模板就完成了,总结起来为三步:
(1)在页面中引入 react 库 和 react-dom 库;
(2)引入 Babel;
(3)创建挂载点。
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>react入门</title>
</head>
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
</script>
</body>
</html>
封装react共有三步:
(1)创建虚拟DOM对象;创建对象包含有3个参数,标签名、属性(对象格式)、标签内的内容;
(2)获取挂载点;
(3)渲染页面。
格式如下:
<body>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<script src="./babel.min.js"></script>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<script type="text/babel">
// 1.创建虚拟DOM对象
const vNode = React.createElement(
//参数表示:标签,属性(对象格式),内容
"div",
{
id: "mydiv",
className: "cls",
},
"hello react!"
);
// 2.获取挂载点
const root = document.getElementById("root");
// 3.页面渲染
ReactDOM.render(vNode, root);
</script>
</body>
</html>
此封装过程也可用JSX语法来写:
<body>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
// 1.创建标签对象
// JSX语法:在JS代码中写XML(类HTML)
const vNode = (
<div id="mydiv" className="cls">
hello react JSX!
</div>
);
// 2.获取挂载点
const root = document.getElementById("root");
// 2.渲染页面
ReactDOM.render(vNode, root);
</script>
</body>
可以看出,JSX语法最大区别在于省去了创建虚拟DON对象的步骤,而是直接创建一个标签对象,在该标签对象中直接按照HTML格式书写代码即可,其余两步则不变。
组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。React 定义组件有两种方式:
函数方式,rfc react function component;某些不能使用;
类方式,rcc react class component;功能更为强大;
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
// 利用函数的封装性和复用性实现组件的复用
// 规范要求:函数名称大写驼峰命名
function Hello() {
return <h1>Hello 组件!</h1>;
}
let h = Hello();
// -------------------------------------------------------------
// JSX语法
// 复用
// JSX语法中调用函数需要写JS语法,JS语法在JSX中写时需要使用{}括起来
// h = (
// <div>
// {Hello()}
// {Hello()}
// {Hello()}
// </div>
// );
// -------------------------------------------------------------
// 语法糖写法:标签方式调用(推荐)
h = <Hello />;
// 语法糖复用
h = (
<div>
<Hello />
<Hello />
<Hello />
</div>
);
// -------------------------------------------------------------
// 渲染
ReactDOM.render(h, document.getElementById("root"));
</script>
</body>
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
// 定义函数组件
// JSX语法中执行JS代码要用{}包裹
function HelloName(props) {
//return <h1>Hello{props}</h1>;
return <h1>Hello{props.name}</h1>;
}
// 调用组件
//let h = HelloName("你好"); //传值
let h = HelloName({ name: "good" }); //传对象
// -----------------------------------------------------------------------
// 语法糖写法(推荐)
h = <HelloName name="语法糖调用" />;
// 复用
h = (
<div>
<HelloName name="语法糖调用" />
<HelloName name="推荐使用语法糖" />
</div>
);
// -----------------------------------------------------------------------
// 渲染
ReactDOM.render(h, document.getElementById("root"));
</script>
</body>
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
// 定义一个类组件
class Hello extends React.Component {
//定义类继承React父类
// 类方法:类属性+类方法
// 类方法
// 默认语法糖标签调用会调用此方法(意思就是如果用语法糖写法只能用render,用其他则会报错,所以建议使用render方法)
render() {
return <h1>Hello 类组件!</h1>;
}
}
// 实例化
let h = new Hello().render();
// 语法糖调用
h = <Hello />;
h = (
<div>
{new Hello().render()}
{new Hello().render()}
<Hello />
<Hello />
</div>
);
// 渲染
ReactDOM.render(h, document.getElementById("root"));
</script>
</body>
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
// 定义类组件并接收参数
class HelloName extends React.Component {
render() {
// this代表当前类内,可以通过它调用类成员
return <h1>Hello {this.props.name}</h1>;
}
}
// 实例化
let h = new HelloName({ name: "类组件传参" }).render();
// 语法糖传参
h = <HelloName name="语法糖传参" />;
// 复用
h = (
<div>
{new HelloName({ name: "JS调用类组件1" }).render()}
{new HelloName({ name: "JS调用类组件2" }).render()}
<HelloName name="语法糖调用1" />
<HelloName name="语法糖调用2" />
</div>
);
// 渲染
ReactDOM.render(h, document.getElementById("root"));
</script>
</body>
React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:React 事件的命名采用小驼峰式(camelCase),而不是纯小写。使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
事件绑定使用的是JS原生写法:
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
// 定义组件+事件处理方法
class App extends React.Component {
// 类成员方法
show() {
alert("点击成功!");
}
render() {
return (
<div>
{/*this代表当前类的成员,此处show不能加括号,因为事件必须点击后执行,如果加了括号就直接执行了*/}
<button onClick={this.show}>点击按钮</button>
</div>
);
}
}
// 渲染
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</body>
事件中this的指向:严格模式下指向window,非严格模式下为undefined;
解决方式:
(1)定义普通函数,调用时 bind 替换 this 并不触发执行;
{this.add.bind(this)}
(2)也使用箭头函数来定义方法,这样正常进行调用;
//定义 add=()=>{} //调用 {this.add}
(3)定义普通函数,调用时先调用箭头函数,再由箭头函数调用普通函数。
{()=>this.add}
如下:使用bind函数替换this指向、使用箭头函数触发
<body>
<!-- 挂载点:后续生成的内容插入这里 -->
<div id="root"></div>
<!-- 引入react的js文件 -->
<script src="./react.development.js"></script>
<script src="./react-dom.development.js"></script>
<!-- 浏览器不识别JSX,需要引入babel来解析翻译,而且需要在script写上对应属性 -->
<script src="./babel.min.js"></script>
<script type="text/babel">
class App extends React.Component {
// 类成员
// 属性
name = "Hello React!";
// 方法
show() {
console.log("普通函数:" + this.name);
}
// 箭头函数方法
show1 = () => {
console.log("箭头函数:" + this.name);
};
render() {
return (
<div>
{/*用bind绑定this,bind(this)将方法中的this替换为App*/}
<button onClick={this.show.bind(this)}>普通函数触发</button>
<br />
<button onClick={this.show1}>箭头函数触发</button>
</div>
);
}
}
// 渲染
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</body>
文章浏览阅读5.4k次。./certbot-auto --nginx --nginx-server-root=/usr/local/nginx/conf_certbot 指定路径
文章浏览阅读3.2k次。java.util.zip.ZipException: error in opening zip file这个问题的字面意思是压缩包打不开,我这出现的问题是jar包损坏,打不开。linux系统可以使用命令判断jar 是否正常:jar -vtf xxx.jar查看jar归档目录[root@localhost classes]# jar -h非法选项: h用法: jar {ctxui}[vfmn0PM..._java.util.zip.zipexception: error in opening zip file
文章浏览阅读1.3k次。题链:https://ac.nowcoder.com/acm/contest/9925/C题意:求 。思路:首先,暴力的话就是枚举i,j。那么算法的话就很容易想到数位dp。看到&运算,肯定是二进制,那就是数二进制位。再看,因为要求i&j==0,那么i和j中每一位中都最多只能有一个1(每一位只能有00,01,10,3种情况);又因为log运算,那么i,j中最高位的1是第几位就是的值。那么,我们枚举每一个最高位(也就是枚举的值),然后数位dp算i&j==0的个数就行了
文章浏览阅读6.7k次。原文地址:https://blog.ch-wind.com/ue4-async-note/虚幻本身有提供一些对异步操作的封装,这里是对这段时间接触到的“非同步”的操作进行的总结。当前使用的UE4版本为4.18.2。在虚幻的游戏制作中,如果不是特殊情况一般不会有用到线程的时候。但是由于实际上虚幻内部是有着许多线程机制的。例如通常的游戏引擎中游戏线程和渲染线程都是独立的,相互之间会存在..._ue tfuture
文章浏览阅读1.2k次。在工作中需要用到curl 远程获取数据,但是访问速度太慢了,有时候需要10几秒到20秒,查了下原因,原来是DNS域名解析速度太慢了,所以,这里我们需要先获取抓取网站的域名的IP,然后再进行处理,经过将域名替换为对应的IP后速度大大的提高了,只用不到3秒就可抓取到数据。 请看示例: ..._提高curl -o 速度
文章浏览阅读4.2k次,点赞4次,收藏39次。LightGBM调参指导针对leaf-wise树的参数优化:num_leaves:控制了叶节点的数目。它是控制树模型复杂度的主要参数。 如果是level-wise,则该参数为2depth2depth,其中depth为树的深度。但是当叶子数量相同时,leaf-wise的树要远远深过level-wise树,非常容易导致过拟合。因此应该让num_leaves小于2depth2depth。在leaf-wise树中,并不存在depth的概念。因为不存在一个从leaves到depth的合理映射。 ..._lightgbm mgts
文章浏览阅读341次。java三大特性之继承通过上一篇对封装的简介,相信大家对java三大特性的封装有了一定的了解。那么除了上一篇博客讲到的封装之外,继承也是java的一大特性。接下来我就谈谈我对java三大特性中的继承的一些看法。继承的概念继承是一种类与类的关系,是一种“is a”的关系。打个比方,狗 “is a” 动物,这里就可以说动物类和狗类之间就是继承关系,也就是说狗类继承了动物类,这里就可以称狗类是..._java三大特性继承
文章浏览阅读136次。https://www.biaodianfu.com/bpr.htmlhttps://www.jianshu.com/p/fd3081abf951https://www.jianshu.com/p/eb54c6a5d08bhttps://blog.csdn.net/qq_38861305/article/details/100942019_贝叶斯个性化推荐 可解释性
文章浏览阅读106次。链接:http://poj.org/problem?id=2761代码:31 struct Node { int l, r, sum; }T[MAXN * 40];32 int a[MAXN], root[MAXN], cnt;33 VI v;34 35 void update(int l, int r, int &x, int y, int po...
文章浏览阅读700次,点赞2次,收藏7次。基于百度飞桨的单/多人行人跟踪代码参考:GitHub - PaddlePaddle/PaddleDetection at release/0.2自己做了一些更改,下面是百度网盘链接:链接:https://pan.baidu.com/s/10UBq2TRtFGORs30P9VaZxg提取码:sdfo复制这段内容后打开百度网盘手机App,操作更方便哦一:百度飞桨的环境配置参考:飞桨PaddlePaddle-源于产业实践的开源深度学习平台二:运行demo:三:代码接口: tools->_百度飞桨跨镜头跟踪人
文章浏览阅读5k次。说在前面最近针对公司项目进行了iPad的适配,发现了很多有关屏幕旋转的适配,发现了一些有趣的问题.1.UICollectionView的itemsize的旋转自适应UIcollectionView在屏幕旋转的过程中,没有进行自动适配,也就是旋转的过程中,collectionView的UIcollectionViewDelegateFlowLayout并没有重新出发调用.解决方案:页面添加屏..._ios 旋转屏幕适配collectionview
文章浏览阅读651次。文章目录调度方式nodeName方式nodeSelect方式故障排除控制器DeploymentSatefulSetDaemonSetJobCronJob常规service和无头服务区别serviceheadless方式k8s配置管理SecretConfigMap调度方式调度方式用于将pod资源调度到相应的node上,可自动分配也可自己指定nodeName:用于将pod调度到指定node上(跳过调度器直接分配)nodeSelect:用于将pod调度到匹配label的node上nodeName方式_vim sts.yaml