前言:
React 的入门教程官方网站上面写的非常好(语言是英语):
https://reactjs.org/docs/forms.html
中文的官方教程:
https://www.reactjscn.com/docs/components-and-props.html
国内的个人教程则属 阮一峰 React 入门实例教程
(有些例子过时了,但github demo近期有修正code), 致敬:
http://www.ruanyifeng.com/blog/2015/03/react.html
出于学习的目的,本人对这些例子做了一一更新。
demo地址:
https://github.com/skyofwinter/react_demo
github 文档传送门:
readme.md
首先可选择下载到本地磁盘 或者 本地新建html 复制文件里的内容
$ git clone git@github.com:skyofwinter/react_demo.git
然后在浏览器上面运行查看
安装:
有2种免安装办法,如果不想下载任何东西,可以直接用第一种做法进行教程学习
- 本文为了简易起见,使用了CDN作为src来源, 真正免安装(官方建议 加上crossorigin)
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
react 官方cdn links介绍
https://reactjs.org/docs/cdn-links.html
2.当然也可以直接使用下载好的js文件
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
一. Hello word 入门
HTML 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--/*1. 选择使用CDN*/-->
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
<title>React 学习</title>
</head>
<body>
<div id="dd">
</div>
<script type="text/babel">
//** your code !!!
</script>
</body>
</html>
<script> 标签的 type 属性为 text/babel . 这是 React 的 JSX 语法, 跟 js不一样. 代码用了三个库: react.js 、react-dom.js 和 babel.min.js(Browser.js) , babel的浏览器版本为browser.js(未精简)和browser.min.js(已精简)
code:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('dd')
);
上面代码将一个 h1 标题,插入 body的div(“dd”) 节点
运行结果:
二. JSX语法
Reac使用JSX,来简化React元素的创建,其语法风格类似于HTML语法风格. 对比如下代码。
<script type="text/babel">
const names = ['Alice', 'Emily', 'Kate'];
const items = names.map((name) =>
<div>hello,{name}!</div>
);
ReactDOM.render(
<h4>{items}</h4>,
document.getElementById("dd")
);
</script>
JSX本身就和XML语法类似,可以定义属性以及子元素。唯一特殊的是可以用大括号来加入JavaScript表达式。遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析.
React 元素其实就是一个简单JavaScript对象,一个React 元素和界面上的一部分DOM对应,描述了这部分DOM的结构及渲染效果。一般我们通过JSX语法创建React 元素,例如:
const element = <h1 className='hello'>Hello, world</h1>;
element是一个React 元素. 在编译环节,JSX 语法会被编译成对React.createElement()的调用,从这个函数名上也可以看出,JSX语法返回的是一个React 元素。上面的例子编译后的结果为:
const element1 = React.createElement(
'h1',
{className: 'hello'},
'Hello, world!'
);
等价于JavaScript
const element = {
const element2 = {
type: 'h1',
props: {
className: 'hello',
children: 'Hello, world'
}
}
二. 组件
React组件最核心的作用是返回React元素, 组件分两种 函数组件(Functional Component )和类组件(Class Component)
函数组件
function HelloMessage(props) {
return <h1>Hello {props.name}</h1>;
};
类组件
function NotesList(props) {
return(
<ol>
{
React.Children.map(props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
};
也有基于组件内部是否维护state作为分法.
本着尽可能使用函数组件减少开销的原则, 没有state则写为函数组件, 这样话基于state分法必要性就很弱了.
三. 再讲state
props 是组件外部传入的,state 是组件内部维护的(需要跟变化挂钩), 同样对于 state的使用也是有个尽量不用的一般通用原则.
1.能用 prop外部传入或者计算得到的,不要用state
2.组件的生命周期内不变的, 没必要用state
3.跟React元素无关的, 用普通变量, 不要用state
4.能减少state 数量的, 就提取等减少数量
对于state的更新上, 修改时候必须使用 setState(), 直接修改this.state,组件不会重新render.
建议把state当作不可变对象,需要改变值得时候, 重新 set一个新的对象给组件( 也就是set的时候 需要是一个新对象)
state使用注意事项:
1.构造函数是唯一能够初始化 this.state 的地方;不要直接更新状态, 这样不会重新渲染组件.
// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});
2.状态更新可能是异步的, React 可以将多个setState() 调用合并成一个调用来提高性能。
3.状态更新合并, 当你调用 setState() 时,React 将你提供的对象合并到当前状态。
因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。
class LikeButton extends React.Component{
constructor(){
super();
this.state = {liked : false};
this.handleClick = this.handleClick.bind(this);
}
handleClick(){
this.setState(prevState => ({
liked:!prevState.liked
}));
console.log("liked " + this.state.liked)
}
render(){
var text = this.state.liked? ' like ':' don\'t like ';
return (
<div>
<button onClick={this.handleClick}>you {text} it, click to change it!</button>
</div>
)
};
}
other
组件生命周期hook:
-
componentWillMount(): Fired once, before initial rendering occurs. Good place to wire-up message listeners.
this.setState
doesn't work here. -
componentDidMount(): Fired once, after initial rendering occurs. Can use
this.getDOMNode()
. -
componentWillUpdate(object nextProps, object nextState): Fired after the component's updates are made to the DOM. Can use
this.getDOMNode()
for updates. - componentDidUpdate(object prevProps, object prevState): Invoked immediately after the component's updates are flushed to the DOM. This method is not called for the initial render. Use this as an opportunity to operate on the DOM when the component has been updated.
- componentWillUnmount(): Fired immediately before a component is unmounted from the DOM. Good place to remove message listeners or general clean up.
-
componentWillReceiveProps(object nextProps): Fired when a component is receiving new props. You might want to
this.setState
depending on the props. -
shouldComponentUpdate(object nextProps, object nextState): Fired before rendering when new props or state are received.
return false
if you know an update isn't needed.
事件绑定:
必须谨慎对待 JSX 回调函数中的 this
,类的方法默认是不会绑定 this
的。如果你忘记绑定 this.handleClick
并把它传入 onClick
, 当你调用这个函数的时候 this
的值会是 undefined
。
这并不是 React 的特殊行为;它是函数如何在 JavaScript 中运行的一部分。通常情况下,如果你没有在方法后面添加 ()
,例如 onClick={this.handleClick}
,你应该为这个方法绑定 this
。