网站首页 > 技术文章 正文
这篇文章是为ReactJs小白准备的,希望他们快速抓住ReactJs的要点并能在实践中随机应变。
两句话版本
- ReactJs把视图更新简化为一个render函数
- render函数接收两个参数,分别是配置项和状态
长版本
ReactJs是一个专注于View的Web前端框架。Web前端的View就是浏览器中的Dom元素,改变View的唯一途径就是修改浏览器中的Dom元素,因此ReactJs的核心任务就是如何修改Dom元素,作为一个成功的框架,ReactJs使修改Dom元素变得高效而又简单。
ReactJs把修改Dom的操作简化成一个函数renderInto(parentDom, props, states)=>htmlString,这个函数的意图就是根据props,states计算出视图对应的html字符串并添加为parentDom的子节点。props和states就是普通的javascript对象,这个函数的核心逻辑就是计算html元素的机构及元素属性然后拼接成字符串返回。作为框架,ReactJs用JSX形式的DSL解决了拼接html的任务并接管了更新到parentDom的职责。看一个例子,理解这个函数并理解ReactJs怎么使用这个函数你就可以一个人开始ReactJs之旅了。
var props = {name: 'myname'};
var states = {amount: 1000};
function render(props, states) {
var title = ’Hello, ' + props.name;
var description = 'You have ' + states.amount + ' score now.';
return (
<div className="score-board">
<h1>{title}</h1>
<p>{description}</p>
</div>
);
}
函数第一行根据props计算title,第二行根据states计算description,最后以JSX形式返回拼接好的html字符串。
如果你用过AngularJs,EmberJs等类似的前端框架,你可能会觉得没什么了不起,不就是把模板和逻辑放到一起吗?是的,没错,但这不仅仅是组织形式上的改变,而是编程隐喻的转变—从复杂的MVC或MVVM模式到简单的render函数。还有一点不同是JSX最终编译成调用react-dom的javascript语句,而不是直接生成字符串。
render函数还只是ReactJs这座冰山的一角,”React”会在render函数的输入变化时再次调用这个函数。再看一个例子。
var props = {name: 'myname'};
var states = {amount: 1000};
function handleClickAdd() {
states = {amount: states.amount + 1};
}
function render(props, states) {
var title = ’Hello, ' + props.name;
var description = 'You have ' + states.amount + ' score now.';
return (
<div className="score-board">
<h1>{title}</h1>
<p>{description}</p>
<button onClick={handleClickAdd}>+1</button>
</div>
);
}
这个例子增加了一个”+1”按钮,当用户点击按钮时会修改states,ReactJs在states变化时的”React”就是再次调用render函数,然后用新输出更新浏览器的dom。
可能你会问,props和states不就是Model吗?是的,可以理解成Model,但此Model非彼Model,props和states都是为View服务的而非和View平起平坐。
可能你还会问,为啥不把props和states合并成一个对象?要回答这个问题,就涉及到复杂视图的场景。想想看,当视图内的元素不断增加时,代码上如何处理,还要在一个render函数里折腾吗?肯定不会。我猜你已经想到了,要把大问题拆小。ReactJs给出的解决方法就是把大视图拆成若干个小视图,每个视图都有自己的render函数,在JSX中可以直接使用视图标签。看一个例子。
var Score = React.createClass({
initialState: function() {
return {amount: 1000};
},
function handleClickAdd() {
this.setState({amount: this.states.amount + 1});
}
render: function() {
var title = ’Hello, ' + this.props.name;
var description = 'You have ' + this.states.amount + ' score now.';
return (
<div className="score-board">
<h1>{title}</h1>
<p>{description}</p>
<button onClick={handleClickAdd}>+1</button>
</div>
);
}
});
var ScoreList = React.createClass({
render() {
return (
<ul className="score-list">
<li><Score name="Tom" /></li>
<li><Score name="Jerry" /></li>
</ul>
);
}
});
ReactDOM.render(
<ScoreList />,
document.getElementById('content')
);
这个例子中有两类View,分别是Score和ScoreList。ScoreList的render函数中使用Score标签并给出配置项name的值。详细看一下Score,ReactJs提供createClass方法定义视图,在render函数中通过this.props访问外部传入的配置项,通过this.states访问视图内部的状态。从意图上看,props外部传入视图的配置项,拥有者是父视图,视图内部只能读取配置项,states的拥有者是视图自身。
区分props和states的结果就是,子视图没办法直接改变父视图,视图改变一定是自触发改变的视图开始向子视图传播。对上面的例子,当Tom的Score改变时,ScoreList其他部分一定不会改变,所以视图更新从Tom的Score视图开始就可以,这就保证了能更高效地计算视图变化,再加上VirtualDom的使用,使ReactJs的效率大大超过其他框架。
当子视图需要改变父视图时,也一定是从父视图开始向下更新。假如上面的例子中ScoreList还有平均分的视图,当Tom的分数改变时,需要更新ScoreList中的平均分。这就需要Score视图在处理”+1”输入时把变化通知到ScoreList,做法时给Score增加配置项,ScoreList中定义更新平均分的函数并把函数作为配置项传给Score。当ScoreList更新时,因为Jerry的props和states都没变化,所以Jerry的Score视图不需要更新。
这就是ReactJs的全部秘密了(不过Web前端本身是一个复杂系统,你还需要了解更多其他内容)。
- 上一篇: 「连载一」「大纲」 前端框架 React 入门教程
- 下一篇: 短剧开发中React前端框架解析
猜你喜欢
- 2025-05-23 React 18:新玩具、新陷阱以及新可能性
- 2025-05-23 第395期Web技术日报(2016-01-22) 使用 React 的一些经验
- 2025-05-23 React 组件渲染慢到崩溃?5 大实战技巧让页面流畅度飙升 80%!
- 2025-05-23 React 入门:从 JavaScript 到 React
- 2025-05-23 01 React入门
- 2025-05-23 前端跳槽突围课:React18底层源码深入剖析(21章完整版)
- 2025-05-23 突发!React官方正式弃用CRA!Next.js、Remix、Vite迁移指南
- 2025-05-23 用JavaScript开发移动原生应用,Facebook正式开源React Native!
- 2025-05-23 性能焦虑!前端人必看!5 个 React 组件优化神技! 颠覆你的认知!
- 2025-05-23 开始学习React - 概览和演示教程
你 发表评论:
欢迎- 07-10Oracle 与 Google Cloud 携手大幅扩展多云服务
- 07-10分享收藏的 oracle 11.2.0.4各平台的下载地址
- 07-10Oracle 和 Microsoft 推出 Oracle Exadata 数据库服务
- 07-10Oracle Database@Azure 推进到南美等新区域并增加了新服务
- 07-10Oracle宣布推出 Oracle Database@AWS 的有限预览版
- 07-10Oracle与Nextcloud合作,推出主权云上的安全协作平台
- 07-10NodeRED魔改版连接MsSql、PostgreSQL、MySQL、OracleDB存储无忧
- 07-10对于企业数据云备份,“多备份”承诺的是成本更低,管理更高效#36氪开放日深圳站#
- 601℃几个Oracle空值处理函数 oracle处理null值的函数
- 593℃Oracle分析函数之Lag和Lead()使用
- 581℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 578℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 573℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 566℃【数据统计分析】详解Oracle分组函数之CUBE
- 552℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 547℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- Oracle 与 Google Cloud 携手大幅扩展多云服务
- 分享收藏的 oracle 11.2.0.4各平台的下载地址
- Oracle 和 Microsoft 推出 Oracle Exadata 数据库服务
- Oracle Database@Azure 推进到南美等新区域并增加了新服务
- Oracle宣布推出 Oracle Database@AWS 的有限预览版
- Oracle与Nextcloud合作,推出主权云上的安全协作平台
- NodeRED魔改版连接MsSql、PostgreSQL、MySQL、OracleDB存储无忧
- 对于企业数据云备份,“多备份”承诺的是成本更低,管理更高效#36氪开放日深圳站#
- 解读丨《归档文件整理规则》— 电子文件元数据存储
- Data Guard跳归档恢复的实践(dataguard failover)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (57)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)