前言:
React 的入門教程官方網(wǎng)站上面寫的非常好(語言是英語):
https://reactjs.org/docs/forms.html
中文的官方教程:
https://www.reactjscn.com/docs/components-and-props.html
國內(nèi)的個(gè)人教程則屬 阮一峰 React 入門實(shí)例教程
(有些例子過時(shí)了,但github demo近期有修正code), 致敬:
http://www.ruanyifeng.com/blog/2015/03/react.html
出于學(xué)習(xí)的目的,本人對這些例子做了一一更新。
demo地址:
https://github.com/skyofwinter/react_demo
github 文檔傳送門:
readme.md
首先可選擇下載到本地磁盤 或者 本地新建html 復(fù)制文件里的內(nèi)容
$ git clone git@github.com:skyofwinter/react_demo.git
然后在瀏覽器上面運(yùn)行查看
安裝:
有2種免安裝辦法悬荣,如果不想下載任何東西,可以直接用第一種做法進(jìn)行教程學(xué)習(xí)
- 本文為了簡易起見赊瞬,使用了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.當(dāng)然也可以直接使用下載好的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 學(xué)習(xí)</title>
</head>
<body>
<div id="dd">
</div>
<script type="text/babel">
//** your code !!!
</script>
</body>
</html>
<script> 標(biāo)簽的 type 屬性為 text/babel . 這是 React 的 JSX 語法, 跟 js不一樣. 代碼用了三個(gè)庫: 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')
);
上面代碼將一個(gè) h1 標(biāo)題贼涩,插入 body的div(“dd”) 節(jié)點(diǎn)
運(yùn)行結(jié)果:
二. JSX語法
Reac使用JSX,來簡化React元素的創(chuàng)建,其語法風(fēng)格類似于HTML語法風(fēng)格. 對比如下代碼巧涧。
<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表達(dá)式褒侧。遇到 HTML 標(biāo)簽(以 < 開頭),就用 HTML 規(guī)則解析谊迄;遇到代碼塊(以 { 開頭)闷供,就用 JavaScript 規(guī)則解析.
React 元素其實(shí)就是一個(gè)簡單JavaScript對象,一個(gè)React 元素和界面上的一部分DOM對應(yīng)统诺,描述了這部分DOM的結(jié)構(gòu)及渲染效果歪脏。一般我們通過JSX語法創(chuàng)建React 元素,例如:
const element = <h1 className='hello'>Hello, world</h1>;
element是一個(gè)React 元素. 在編譯環(huán)節(jié)粮呢,JSX 語法會被編譯成對React.createElement()的調(diào)用婿失,從這個(gè)函數(shù)名上也可以看出,JSX語法返回的是一個(gè)React 元素啄寡。上面的例子編譯后的結(jié)果為:
const element1 = React.createElement(
'h1',
{className: 'hello'},
'Hello, world!'
);
等價(jià)于JavaScript
const element = {
const element2 = {
type: 'h1',
props: {
className: 'hello',
children: 'Hello, world'
}
}
二. 組件
React組件最核心的作用是返回React元素, 組件分兩種 函數(shù)組件(Functional Component )和類組件(Class Component)
函數(shù)組件
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>
);
};
也有基于組件內(nèi)部是否維護(hù)state作為分法.
本著盡可能使用函數(shù)組件減少開銷的原則, 沒有state則寫為函數(shù)組件, 這樣話基于state分法必要性就很弱了.
三. 再講state
props 是組件外部傳入的豪硅,state 是組件內(nèi)部維護(hù)的(需要跟變化掛鉤), 同樣對于 state的使用也是有個(gè)盡量不用的一般通用原則.
1.能用 prop外部傳入或者計(jì)算得到的,不要用state
2.組件的生命周期內(nèi)不變的, 沒必要用state
3.跟React元素?zé)o關(guān)的, 用普通變量, 不要用state
4.能減少state 數(shù)量的, 就提取等減少數(shù)量
對于state的更新上, 修改時(shí)候必須使用 setState(), 直接修改this.state,組件不會重新render.
建議把state當(dāng)作不可變對象挺物,需要改變值得時(shí)候, 重新 set一個(gè)新的對象給組件( 也就是set的時(shí)候 需要是一個(gè)新對象)
state使用注意事項(xiàng):
1.構(gòu)造函數(shù)是唯一能夠初始化 this.state 的地方;不要直接更新狀態(tài), 這樣不會重新渲染組件.
// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});
2.狀態(tài)更新可能是異步的, React 可以將多個(gè)setState() 調(diào)用合并成一個(gè)調(diào)用來提高性能懒浮。
3.狀態(tài)更新合并, 當(dāng)你調(diào)用 setState() 時(shí),React 將你提供的對象合并到當(dāng)前狀態(tài)识藤。
因?yàn)?this.props 和 this.state 可能是異步更新的砚著,你不應(yīng)該依靠它們的值來計(jì)算下一個(gè)狀態(tài)。
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.
事件綁定:
必須謹(jǐn)慎對待 JSX 回調(diào)函數(shù)中的 this
痴昧,類的方法默認(rèn)是不會綁定 this
的稽穆。如果你忘記綁定 this.handleClick
并把它傳入 onClick
, 當(dāng)你調(diào)用這個(gè)函數(shù)的時(shí)候 this
的值會是 undefined
。
這并不是 React 的特殊行為赶撰;它是函數(shù)如何在 JavaScript 中運(yùn)行的一部分舌镶。通常情況下柱彻,如果你沒有在方法后面添加 ()
,例如 onClick={this.handleClick}
乎折,你應(yīng)該為這個(gè)方法綁定 this
绒疗。