react之“hello world”

               我相信大家踏入一门编程语言的第一步就是“哈喽,我的”。恩,学会这一句,世界就会是我们的了。为了降低学习成本,首先避开了“繁琐”的服务器环境搭建,直接依赖浏览器环境,在客户端先熟悉一下React语法和一些基础知识。

虽然不用配置服务器环境,但是要引入相关JS:react.js, react-dom.js, babel.min.js (不能太懒呀!)


我这边打算直接通过例子来总结知识点,下面是一个最简单的 "hello world" 实现程序。


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>react-hello-world</title>
	<script src="react.js"></script>
	<script src="react-dom.js"></script>
	<script src="babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type='text/babel'>
	ReactDOM.render(<h1>hello world</h1>, document.getElementById('app'));
</script>
</body>
</html>

总结:

1.除了引入react相关的js文件外,还额外引入了babel这个插件,主要是为了对我们的js代码进行编译,把es6语法转换为es5(当然上面这个例子中我们还没用到ES6语法,下面例子会展示),我们需要将script中的type改成text/babel,这样babel.js才能正确转化。我们还发现了js和html混合使用的方法,这里的方法和我们以前不一样,没加任何引号,这种方法叫做jsx,是react发明的一种写法,也是需要babel去转换的。

what!什么是jsx写法?http://www.cnblogs.com/zourong/p/6043914.html

ps: jsx语法中注释代码的话这样:   { /*      注释代码      */}

es6就不用我多说了吧,前面也有相关学习笔记:http://blog.csdn.net/liuzijiang1123/article/details/56835823

(主要掌握:import,export,class,const,let,arrow function)


目前react的代码书写规范是:jsx+es6;

ES5和ES6对于React的开发书写是有一定差异的,大家可以去网上多找一下类似的文章:http://www.cnblogs.com/yongjz/p/5356914.html


2.ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。

在这里我们自己创建了一个html节点<h1>hello world</h1>这个节点,不过是个虚拟的dom节点,并没有真正在我们页面上出现,我们出现将其与页面中真正存在的dom节点相关联,就是"挂载"在真正的dom节点旗下。页面加载成功后,你可以打开F12看,这个<h1>节点“挂载”在我们的"app"节点下面。


下面再举一个hello world的例子,变个花样~


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>react-hello-world</title>
	<script src="react.js"></script>
	<script src="react-dom.js"></script>
	<script src="babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type='text/babel'>
	class HelloMessage extends React.Component { //notice use of React.Component
        constructor() {
			super();
        	}
          render() {
                return (
		  <div>
                	<h1>{this.props.says}</h1>
                  </div>
                );
            }
        };

        ReactDOM.render(<HelloMessage/>, document.getElementById('app'));
</script>
</body>
</html>


上面这个hello world例子就比第一个的“复杂”一些。
总结:

1.React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。这里用到了es6中的新语法class,我们创建了一个HelloMessage的类,继承React.Component类;定义了一个render方法,用来返回我们的html模块。


注意:

A.添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

B.组件类的第一个字母必须大写,否则会报错,比如HelloMessage不能写成helloMessage。另外,组件类只能包含一个顶层标签,否则也会报错,这个就是为什么我们在render中返回的html标签中总会有一个大的标签把要返回的内容包裹起来(我这里是用div),因为ReactDOM.render第一个参数只能接受一个虚拟的DOM节点。


下面是参考阮老师的博客进行的一些拓展:

拓展1:

组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如<HelloMessage says="Hello world"> ,就是 HelloMessage 组件加入一个 says属性,值为 Hello world.组件的属性可以在组件类的this.props 对象上获取,比如 says 属性就可以通过 this.props.says读取,这样我们又多了一种实现hello world的方法。


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>react-hello-world</title>
	<script src="react.js"></script>
	<script src="react-dom.js"></script>
	<script src="babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type='text/babel'>
	class HelloMessage extends React.Component { //notice use of React.Component
        constructor() {
		 super();
        	}
          render() {
                return (
		  <div>
                	<h1>{this.props.says}</h1>
                  </div>
                );
            }
        };

        ReactDOM.render(<HelloMessage says="Hello world"/>, document.getElementById('app'));
</script>
</body>
</html>

由于class有一个本身也会有一个属性,我们还可以把这个hello world定义到它的属性里面:

constructor() {
		super();
		this.says="hello world";
        }


<h1>{this.says}</h1>
这样修改也能通过属性来实现hello world。


拓展2:

this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是this.props.children 属性。它表示组件的所有子节点。

下面这个例子也可以输出"hello world",通过寻找组件下面的所有子节点来显示。


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>react-hello-world</title>
	<script src="react.js"></script>
	<script src="react-dom.js"></script>
	<script src="babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type='text/babel'>
	class HelloMessage1 extends React.Component{
			constructor() {
				super();
				}

		render() {
			return (
			<ol>
			     {
				React.Children.map(this.props.children, function (child) {
				return <li>{child}</li>;
				})
			     }
			</ol>
			);
		    }
		};


	ReactDOM.render(
		<HelloMessage1>
			<span>hello</span>
			<span>world</span>
		</HelloMessage1>,
		document.getElementById('app')
	);
</script>
</body>
</html>


拓展3:获取真实的DOM节点

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做DOM diff ,它可以极大提高网页的性能表现。但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性。


下面这个代码中的功能是,当我去点击按钮时,我们的text就会获取到焦点;这个时候就需要获取到我们真实的DOM节点( text文本框 );为了做到这一点,文本输入框必须有一个ref 属性,然后this.refs.[refName] 就会返回这个真实的 DOM 节点。由于this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。通过为组件指定Click 事件的回调函数,确保了只有等到真实 DOM 发生Click 事件之后,才会读取this.refs.[refName] 属性。


当然这里还需要注意的是:

1.我们这里给按钮添加onClick触发事件,这里必须用驼峰式!!不能用onclick,因为html里面是不区分大小写的,但是js里面区分,我们这里需要写成onClick。

2.我们这里用的是es6的写法,onClick里面的this没有绑定,我们需要重新绑定一下我们的this,否则会报错。可以参考:https://segmentfault.com/q/1010000008155467

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>react-hello-world</title>
	<script src="react.js"></script>
	<script src="react-dom.js"></script>
	<script src="babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type='text/babel'>
	class HelloMessage extends React.Component { //notice use of React.Component
        constructor() {
		super();	
        }
     
	handleClick(){
		this.refs.mytext.focus();
	}
        render() {
              return (
		<div>
	           <input type="text" ref="mytext"/>
	           <input type="button" value="fous" onClick={()=>this.handleClick()} />
		</div>
               );
           }
       };
       ReactDOM.render(<HelloMessage/>, document.getElementById('app'));


	</script>
</body>
</html>

拓展4:

组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI,这种状态由this.state来表示,也可以代表一种组件的属性;由于this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而this.state 是会随着用户互动而产生变化的特性。(this.props 钟情,this.state花心)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>react-hello-world</title>
	<script src="react.js"></script>
	<script src="react-dom.js"></script>
	<script src="babel.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type='text/babel'>
	class HelloMessage extends React.Component { //notice use of React.Component
        constructor() {
			super();
			this.state={
				liked:false
			}
        	}
       
	handleClick(){
			this.setState({liked: !this.state.liked});
		}
        render() {
              var text = this.state.liked ? 'like' : 'haven\'t liked';
		return (
			<p onClick={()=>this.handleClick()}>
			You {text} this  Click to toggle.
			</p>
		);
            }
        };
        ReactDOM.render(<HelloMessage/>, document.getElementById('app'));
</script>
</body>
</html>

上面代码是一个LinkButton组件,在ES6中我们直接在构造函数的this.state中定义初始状态,也就是一个对象,可以通过其获取属性。当用户点击组件,导致状态变化,this.setState方法就修改状态值,每次修改以后,自动调用this.render 方法,再次渲染组件。


拓展5:

组件的生命周期成三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数(除了移除DOM),will函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

  • componentWillMount()
  • componentDidMount()
  • componentWillUpdate(object nextProps, object nextState)
  • componentDidUpdate(object prevProps, object prevState)
  • componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。

  • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
  • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

当一个组件被调用的时候先执行getDefaultProps,getInitialState获取他的默认属性和状态(es6中换了其他的写法,写在了constructor这个函数中),然后执行componentWillMount(即将渲染),接下来渲染到dom树上(触发render函数),渲染完成触发componentDidMount函数;

这时候,该组件就进入了一个running状态,并监视他的props和state以及被移除事件:

  当props发生变化时执行componentWillReceiveProps然后去判断是否需要重新渲染(shouldComponentUpdate),如果不需要则继续保持running状态;如果需要则如初始时一样,执行componentWillMount(即将渲染),接下来渲染到dom树上,渲染完成触发componentDidMount函数,保持running状态继续监视;

  当state发生变化时,则直接判断是否需要重新渲染(shouldComponentUpdate),然后根据是否需要决定执行渲染过程还是继续保持running状态;

  当该组件被移除(unmount)时,将直接执行componentWillUnmount,该组件从dom树上消失;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值