好久没写文章了,今天来分享一篇 关于 react 的 helloWord 。如果你也是刚开始学习react,或者已经久仰 react 并开始着手学习,那或许这篇文章能给你一点启发。
文章围绕一个小案例来学习 -- 创建一个简单的单页应用
一、了解什么是单页应用,什么是多页应用
1、以前你做的或看到的网站可能包含多个单独的网页,主页一个导航,点开打开另一个网页,这就是传统的多页应用。多页应用有什么优缺点呢?
首先对用户的体验不是很好,销毁一个网页,再重新打开另一个网页。其次数据的传递也不是很便利,利用cookie和服务端来保存用户数据是一种普遍的处理方式,但是 不 方 便 。但多页应用不用考虑新旧页面的变化,一个多页应用每一页都会重新建立。
2、单页应用(SAP)
,单页应用不需要重新加载整个页面,单页应用可以对整个页面进行区块化划分,加载和卸载某一块区块。在单页应用中,我们的大部分时间会花在保持数据与 UI 同步上。
那单页应用有什么缺陷吗?有地,不如单页应用回频繁的操作dom ,对节点的删除和添加,这样加大了浏览器对性能的要求。
二、react的出现
首先单页应用无疑来说对用户的体验更加友好的,那么站在用户的角度,我们只要解决单页应用的缺陷不就两全其美了。
Facebook (和 Instagram) 觉得该解决这些问题了。在经历了足够的单页应用实践后,他们发布了一个叫做 React
的库。react
并不关心UI 开始是什么状态,只关心UI的最终状态。因为 DOM 操作是真的很慢,所以React不会直接 修改 DOM,而是修改内存中的虚拟 DOM,React在每次需要渲染时,会先比较当前DOM内容和待渲染内容的差异,然后再决定如何最优地更新DOM。
或许你听说过 MVC MVP MVVC 等一些设计模式,你可以吧 react 当中 V 层,也就是 view 层
,专门来负责 ui 的处理,react 把页面的各个功能分成一小块(俗称组件)
,更新页面的时候只更新改动过的组件即可。
三、开始进入正题。
下面咱们围绕一个 单页应用的demo ,来细说 react 。
思路是这样的 ,先讲解一下 react 的一些新知识和概念
-- 上代码
-- 对代码进行解释
-- 总结
1、依赖库
<script src="https://unpkg.com/react@15.3.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.3.2/dist/react-dom.js"></script>
第一行引入 核心 React 库,第二行引入 React DOM 库。如果没有这两个库,我们是没法创建 React 应用的。
Web 应用(以及浏览器显示的其它一切)是由 HTML、CSS 和 JavaScript 组成的:所以,我们还需要在两个 script
标记下添加对 Babel JavaScript
编译器的引用:
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
Babel
可以做很多很酷的事情,但是我们关心的是将 JSX
变成 JavaScript
的能力。 JSX
下面解释。
添加
<script src="https://npmcdn.com/react-router@2.4.0/umd/ReactRouter.min.js"></script>
ReactRouter
为由 React
创建的单页应用提供了路由能力.因为在原始的多页应用中,地址栏 url 是实时对应你访问页面的地址的。但在单页应用中,组件的替换或添加不能在地址栏url实时对应,当用户刷新或后退网页,就不在对应用户原先访问的那个页面了。所以 ReactRouter
是来帮咱们解决这一问题的一个 js库
应用模板:
<!DOCTYPE html>
<html>
<head>
<title>React Components</title>
<script src="https://unpkg.com/react@15.3.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.3.2/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://npmcdn.com/react-router@2.4.0/umd/ReactRouter.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
</script>
</body>
</html>
2、JSXJSX
你可以把它看做可以写 js 和 html 的混合标记。我们通常在 js 里面动态的创建一个html元素是这样的:
var xxx = document.createElement("div");
xxx.className = "xxx";
xxx.xxx
.......
xxx.appendChild(xxx);
但有了 JSX ,你就可以这样:
<body>
<script type="text/babel">
ReactDOM.render(
<div>Batman</div>,
document.body
);
</script>
</body>
运行上面的代码是在 body
显示 Batman
的字样 ,后面会解释 ,反正要创建 html元素,直接写 html语法就可以了,是不是很酷。
3、组件的概念
单页应用最重要的就是将页面组件化。
最开始我们创建组件的方式是用 React.createClass
一个简单的 helloword组件
:
var HelloWorld = React.createClass({
render: function() {
return (
<p>你好,react 组件!</p>
);
}
});
上面是利用 React.createClass
创建一个组件,组件有一个强制性的属性render
,render
方法的return
返回组件的内容。
组件的引用:
ReactDOM.render(
<HelloWorld/>,
document.body
);
render
将 HelloWorld组件
添加到 body
中
也许你会很好奇在浏览器上显示是什么结构的:
4、一个单页应用的demo
有了上面的基础知识,咱们利用demo进一步学习。
效果图:点击 nav
会切换不同的页面,但注意是单页的!
(1)、创建导航条组件
var App = React.createClass({
render: function() {
return (
<div>
<h1>Simple SPA</h1>
<ul className="header">
<li>Home</li>
<li>Stuff</li>
<li>Contact</li>
</ul>
<div className="content">
</div>
</div>
)
}
});
上面简单的创建了个导航条的组件,其中 ``<div className="content"> 用来存放内容组件。
可能你会注意到 这里用来 className
属性 而不是 class
,原因是 class
是 JavaScript
中的一个特殊关键字
,所以保留。react
用 className
来加载样式。
(2)、创建 Home 组件:
var Home = React.createClass({
render: function() {
return (
<div>
<h2>HELLO</h2>
<p>Cras facilisis urna ornare ex volutpat, et
convallis erat elementum. Ut aliquam, ipsum vitae
gravida suscipit, metus dui bibendum est, eget rhoncus nibh
metus nec massa. Maecenas hendrerit laoreet augue
nec molestie. Cum sociis natoque penatibus et magnis
dis parturient montes, nascetur ridiculus mus.</p>
<p>Duis a turpis sed lacus dapibus elementum sed eu lectus.</p>
</div>
);
}
});
到这里应该比较能适应 React
创建组件的方式了吧。 render
方法里面有个 return
来返回组件的内容。
(3)、创建 Contact 和 Stuff 组件:
var Contact = React.createClass({
render: function() {
return (
<div>
<h2>GOT QUESTIONS?</h2>
<p>The easiest thing to do is post on
our <a href="http://forum.kirupa.com">forums</a>.
</p>
</div>
);
}
});
var Stuff = React.createClass({
render: function() {
return (
<div>
<h2>STUFF</h2>
<p>Mauris sem velit, vehicula eget sodales vitae,
rhoncus eget sapien:</p>
<ol>
<li>Nulla pulvinar diam</li>
<li>Facilisis bibendum</li>
<li>Vestibulum vulputate</li>
<li>Eget erat</li>
<li>Id porttitor</li>
</ol>
</div>
);
}
});
(5)、往导航条添加链接
组件都创建好了,接下来就是怎么将组件对应起来咯,
var App = React.createClass({
render: function() {
return (
<div>
<h1>Simple SPA</h1>
<ul className="header">
<li><IndexLink to="/" activeClassName="active">Home</IndexLink ></li>
<li><Link to="/stuff" activeClassName="active">Stuff</Link></li>
<li><Link to="/contact" activeClassName="active">Contact</Link></li>
</ul>
<div className="content">
{this.props.children}
</div>
</div>
)
}
});
App
是刚开始创建的导航条组件,这里咱们用到了一个 React Router
的 Link
组件,其实它是跟 <a 标记
类似 ,但提供的功能更多 , to
就好比 <a 标记
的 href
,指向一个链接。
那上面代码就好理解啦,to=“/"
就是指向当前链接 , to="/stuff"
就是指向 /stuff
链接。
细心的你还会发现第一个 li
是 IndexLink组件
,这个跟Link
有什么不同呢。IndexLink组件
是用来初始化时候指定的链接。
咱们在 <div className="content">
里面放的不是上面创建的那几 Home
、Stuff
、Contact
个组件 ,而是 放了个 {this.props.children}
,这是啥意思呢,这里你先知道 this.props.children
可以用于访问 子元素 以及该组件所有的任何子孙元素。这里用这个属性来加载子组件,后面会做解释
(6)、加载组件
上面那几步都是创建了组件,怎么把组件加载到页面中还得利用 ReactDOM.render
ReactDOM.render(
<Router>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="stuff" component={Stuff}></Route>
<Route path="contact" component={Contact} />
</Route>
</Router>,
destination);
上面用到了 Route
组件, 当你访问的 url
为 /stuff
时就加载组件 Stuff(
Stuff组件咱们前面已经写好了),当你访问 url
为 /Contact
时 就加载组件 Contact
,那访问 url
为 /
呢 ,那就加载 `IndexRoute ,这也是
IndexRoute 不同于组件
Route `。
那结合第五部统一分析下:
如下,
<li><Link to="/stuff" activeClassName="active">Stuff</Link></li>
Link to
是给 组件`` Stuff指定了链接 ,
那么,
<Route path="stuff" component={Stuff}></Route>
Route
组件是给 链接定义了对应的组件,最后由
{this.props.children}
来加载显示出对应的组件。
结束语:
本篇文章大概讲了 react 怎么创建一个单页应用,让大家了解一下react 。很对具体的知识点多略过,想深入学习可以看以下这些教程:
React Router 使用教程
React 简介
下面上完整代码:
<!DOCTYPE html>
<html>
<head>
<title>React! React! React!</title>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
<script src="https://npmcdn.com/react-router@2.4.0/umd/ReactRouter.min.js"></script>
<style type="text/css">
body {
background-color: #FFCC00;
padding: 20px;
margin: 0;
}
h1, h2, p, ul, li {
font-family: Helvetica, Arial, sans-serif;
}
ul.header li {
display: inline;
list-style-type: none;
margin: 0;
}
ul.header {
background-color: #8fd2ff;
padding: 0;
}
ul.header li a {
color: #FFF;
font-weight: bold;
text-decoration: none;
padding: 20px;
display: inline-block;
}
.content {
background-color: #FFF;
padding: 20px;
}
.content h2 {
padding: 0;
margin: 0;
}
.content li {
margin-bottom: 10px;
}
.active {
background-color: #0099FF;
}
</style>
</head>
<body>
<div class="content" id="container"></div>
<script type="text/babel">
var destination = document.querySelector("#container");
var { Router,
Route,
IndexRoute,
IndexLink,
Link } = ReactRouter;
var Home = React.createClass({
render: function() {
return (
<div>
<h2>HELLO</h2>
<p>Cras facilisis urna ornare ex volutpat, et
convallis erat elementum. Ut aliquam, ipsum vitae
gravida suscipit, metus dui bibendum est, eget rhoncus nibh
metus nec massa. Maecenas hendrerit laoreet augue
nec molestie. Cum sociis natoque penatibus et magnis
dis parturient montes, nascetur ridiculus mus.</p>
<p>Duis a turpis sed lacus dapibus elementum sed eu lectus.</p>
</div>
);
}
});
var Contact = React.createClass({
render: function() {
return (
<div>
<h2>GOT QUESTIONS?</h2>
<p>The easiest thing to do is post on
our <a href="http://forum.kirupa.com">forums</a>.
</p>
</div>
);
}
});
var Stuff = React.createClass({
render: function() {
return (
<div>
<h2>STUFF</h2>
<p>Mauris sem velit, vehicula eget sodales vitae,
rhoncus eget sapien:</p>
<ol>
<li>Nulla pulvinar diam</li>
<li>Facilisis bibendum</li>
<li>Vestibulum vulputate</li>
<li>Eget erat</li>
<li>Id porttitor</li>
</ol>
</div>
);
}
});
var App = React.createClass({
render: function () {
return (
<div>
<h1>simple app </h1>
<ul className="header">
<li><IndexLink to = "/" activeClassName="active">Home</IndexLink></li>
<li><Link to = "/Stuff" activeClassName="active">Stuff</Link> </li>
<li><Link to = "/Contact" activeClassName="active">Contact</Link> </li>
</ul>
<div className="content">
{this.props.children}
</div>
</div>
)
}
});
ReactDOM.render(
<Router>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path = "Stuff" component = {Stuff}/>
<Route path = "Contact" component = {Contact}/>
</Route>
</Router>,
destination
);
</script>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。