目錄
- html模板
- ReactDOM.render()
- JSX 語法
- 組件 & props
- props & 純函數
- 事件
- 列表渲染
- 條件渲染
- this.state
- style和class
- 生命週期
- 表單
- 獲取真實的DOM節點
- this.props.children
一、html模板
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 生產環境中不建議使用 -->
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
</head>
<body>
<div id="example"></div>
// script的類型必須是text/babel
<script type="text/babel">
// todo
</script>
</body>
</html>
二、ReactDOM.render()
作用: 編譯模板,把模板掛載到指定的節點上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
ReactDOM.render(
<h1>hello world</h1>,
document.getElementById('root')
)
</script>
三、JSX 語法
說明: jsx語法html代碼和js代碼可以混寫而不需要加引號,可以這樣做的原因是React和到jsx代碼後會進行編譯,使代碼正確運行.當然jsx也是有它自己本身的規則:
- js代碼需要用{}括起來
- React編譯規則: 遇到<開頭就看作是html,遇到{開頭則視爲js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
<script type="text/babel">
const person = {
name: 'huruqing',
age: 108
};
const element =
<h1>
<p>姓名: {person.name}</p>
<p>年齡: {person.age}歲</p>
</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
</script>
四、組件
- 用es5定義一個react組件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
// es5組件的寫法,一個函數就是一個組件
function Welcome(props) {
return (
<h1>
<p>姓名: {props.person.name}</p>
<p>年齡: {props.person.age}</p>
</h1>
)
}
const person = {
name: 'huruqing',
age: 108
}
ReactDOM.render(
<Welcome person={person} />,
document.getElementById('root')
)
</script>
- es6的class和class繼承
<script>
/**
* 面向對象中的繼承
* es6中的類和類的繼承
*/
// 定義一個類
class Person {
// 構造器(初始化類的實例)
constructor() {
// alert('哈哈哈哈');
this.mouth = '1張';
this.leg = '兩條';
}
eat() {
console.log('人類是個吃貨');
}
speak() {
console.log('會說人話');
}
}
var person = new Person();
console.log(person);
// 繼承
class Man extends Person {
constructor(name,age) {
// 執行父類構造器
super();
this.name = name;
this.age = age;
}
}
var man = new Man('張三',100);
console.log(man);
console.log(man.leg);
man.speak();
</script>
- 用es6定義個react組件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
<h1>
<p>姓名: </p>
<p>年齡: </p>
</h1>
</div>
</body>
</html>
<script type="text/babel">
/**
* es6使用class的形式來創建組件,繼承React的Component類,
* 後面我們更多的使用這種方式來創建組件
*/
class Welcome extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<h1>
<p>姓名: {this.props.person.name}</p>
<p>年齡: {this.props.person.age} </p>
</h1>
)
}
}
const person = {
name: 'huruqing',
age: 108
}
ReactDOM.render(
<Welcome person={person} />,
document.getElementById('root')
)
</script>
五、props和純函數
- 相同的輸入有相同的輸出,輸入可以確定輸出,這就是純函數
- 對待props就像對待純函數一樣,遵循可以通過輸入確定輸出
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
<script type="text/babel">
// 這是個純函數,輸入什麼,得到什麼是一定的,同樣的輸入必定有同樣的輸出
const sum = (a, b) => {
return a + b;
}
sum(2,3); // 5
sum(2,3); // 5
// 這個函數是不純的,因爲它修改了外部傳進來的參數
let count = 0;
const getResult = (num) => {
count++;
return num*num + count;
}
getResult(2); // 5
getResult(2); // 6
// 所有的react組件都必須遵守的一條規則:
// 對待props就像對待純函數一樣,遵循可以通過輸入確定輸出
</script>
六、綁定事件
- 事件綁定的函數的this的指向會改變,需要使用bind來綁定函數的指向
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
<script type="text/babel">
class Demo extends React.Component {
constructor(props) {
super(props);
// 讓函數的this指向class的實例
this.handleClick = this.handleClick.bind(this);
}
handleClick (){
this.getList();
}
getList() {
alert('獲取列表數據');
}
render() {
return (
<div>
<button onClick={this.handleClick}>
click
</button>
</div>
);
}
}
ReactDOM.render(
<Demo />,
document.getElementById('app')
)
</script>
- 事件傳參的方式
react可以在{} 裏面執行一個函數的調用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
class Demo extends React.Component {
constructor(props) {
super(props);
this.toDetail = this.toDetail.bind(this);
}
toDetail(id) {
console.log(event);
alert(id);
}
render() {
return (
<div>
<ul>
<li> <button onClick={() => {this.toDetail(1001)}}>電影1</button> </li>
<li> <button onClick={() => {this.toDetail(1002)}}>電影2</button> </li>
<li> <button onClick={() => {this.toDetail(1003)}}>電影3</button> </li>
</ul>
</div>
)
}
}
ReactDOM.render(
<Demo />,
document.getElementById('root')
)
</script>
七、列表渲染
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
class List extends React.Component {
constructor(props) {
super(props);
}
render() {
let heroList = this.props.heroList;
return (
<ul>
{heroList.map(hero =>{
return (
<li key={hero.id}>
{hero.heroName} -- {hero.role}
</li>
)
}
)}
</ul>
)
}
}
const heroList = [
{id: 1, heroName: '亞瑟', role: '戰士'},
{id: 2, heroName: '牛魔王', role: '戰士'},
{id: 3, heroName: '魯班七號', role: '射手'}
];
ReactDOM.render(
<List heroList={heroList} />,
document.getElementById('root')
);
</script>
八、條件渲染
- 通過 if 來控制渲染內容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
<script type="text/babel">
class Welcome extends React.Component {
constructor(props) {
super(props);
}
render() {
// 使用if else判斷變量isLogin的值來決定顯示什麼內容
if (this.props.isLogin) {
return (
<h1>歡迎回來, <button style={{color: 'blue'}}>退出登錄</button></h1>
)
} else {
return (
<h1>你還沒登錄, <button style={{color: 'red'}}>請登錄</button></h1>
)
}
}
}
ReactDOM.render(
<Welcome isLogin={false}/>,
document.getElementById('app')
)
</script>
- 通過三目運算符來判斷
使用三目運算符判斷變量isLogin的值來決定顯示什麼內容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>三目運算符</title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
<script type="text/babel">
class Welcome extends React.Component {
constructor(props) {
super(props);
}
render() {
/**
* 通過變量isLogin來決定顯示什麼內容
* 使用三目運算符(內容較短用三目運算符)
* 再長一點用上面if else的方式
* 更長的內容封裝成一個組件更合適
*/
return (
this.props.isLogin?
<h1>歡迎回來, <button style={{color: 'blue'}}>退出登錄</button></h1>:
<h1>你還沒登錄, <button style={{color: 'red'}}>請登錄</button></h1>
)
}
}
ReactDOM.render(
<Welcome isLogin={true}/>,
document.getElementById('app')
)
</script>
- 通過與運算符 && 進行控制
相當於if沒有else的情況
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>三目運算符</title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
<script type="text/babel">
class Welcome extends React.Component {
constructor(props) {
super(props);
}
render() {
/**
* 如果值爲true就顯示,爲false不顯示,相當於vue的v-show
*/
return (
this.props.show &&
<p>
React 起源於 Facebook 的內部項目,因爲該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram
的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。
</p>
)
}
}
ReactDOM.render(
<Welcome show={true}/>,
document.getElementById('app')
)
</script>
九、this.state和this.setState
例1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- react框架文件 -->
<script src="lib/react.development.js"></script>
<!-- react用來渲染頁面的文件 -->
<script src="lib/react-dom.development.js"></script>
<!-- 用來編譯jsx語法的庫 -->
<script src="lib/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
<script type="text/babel">
class Login extends React.Component {
constructor(props) {
super(props);
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.state = {
isLogin: false
}
}
render() {
let { isLogin } = this.state;
return (
<div>
{isLogin?<p>****5539<button onClick={this.logout}>退出登陸</button></p>:<button onClick={this.login}>立即登陸</button>}
</div>
)
}
logout() {
this.setState({
isLogin: false
})
}
login() {
this.setState({
isLogin: true
})
}
}
ReactDOM.render(
<Login/>,
document.getElementById('app')
)
</script>
</body>
</html>
例2
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>三目運算符</title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
<script type="text/babel">
class Welcome extends React.Component {
constructor(props) {
super(props);
// state的初始值
this.state = {
show: true
}
this.toggleMsg = this.toggleMsg.bind(this);
}
toggleMsg(flag) {
// 修改state裏show的值
this.setState({
show: flag
})
}
render() {
return (
<div>
<button onClick={()=> {this.toggleMsg(true)}}>顯示</button>
<button onClick={()=> {this.toggleMsg(false)}}>隱藏</button>
<hr />
{this.state.show &&
<p>React 起源於 Facebook 的內部項目,因爲該公司對市場上所有 JavaScript MVC
框架,都不滿意,就決定自己寫一套,用來架設 Instagram
的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。
</p>
}
</div>
)
}
}
ReactDOM.render(
<Welcome />,
document.getElementById('app')
)
</script>
十、樣式和屬性
- class使用className代替
- style需要用{{}},外面的{}代表這是js代碼,裏面的{}則是個js對象
- 屬性是個變量加上{}即可
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<style>
.green {
color: green;
}
</style>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
let bg = '#999';
let imgUrl = 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=1598000148,3084276147&fm=58&s=36F6EC36C8A47E92227DC7C502007026';
ReactDOM.render(
<div>
<p style={{backgroundColor: bg,width: '200px'}}>hello react</p>
<p className="green">我的react</p>
<img src={imgUrl}/>
</div>,
document.getElementById('root')
)
</script>
十一、生命週期
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
/**
* react的生命週期分成三種
* 1. mount 掛載
* 2. update 更新
* 3. unmount 卸載
*/
class Hello extends React.Component {
componentWillMount() {
console.log('即將掛載');
}
componentDidMount() {
console.log('已掛載');
}
componentWillUpdate(nextProps, nextState) {
console.log('將要更新');
}
componentDidUpdate(prevProps, prevState) {
console.log('更新完畢');
}
// 默認每一次的修改都觸發頁面更新,此函數用於干預是否要更新,用於性能優化,
shouldComponentUpdate(nextProps, nextState) {
}
componentWillUnmount() {
console.log('將要卸載');
}
render() {
return <div>生命週期</div>
}
}
ReactDOM.render(
<Hello name="world"/>,
document.getElementById('root')
);
</script>
十二、表單
- 單個input標籤輸入,讓輸入的數據與react數據流同步
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('你輸入的用戶名是: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<p>
用戶名:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</p>
<input type="submit" value="提交" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
)
</script>
- 多個input表單輸入
如果有多個input標籤輸入,我們是否需要爲每一個input綁定一個事件呢,會不會太麻煩了,
其實不用,我們可以像下面這樣來處理
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
username: 'huruqing',
password: 123456,
msg: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<div>
<form>
<label>
用戶名:
<input
name="username"
type="text"
value={this.state.username}
onChange={this.handleChange} />
</label>
<br />
<label>
密碼:
<input
name="password"
type="text"
value={this.state.password}
onChange={this.handleChange} />
</label>
</form>
<p>
你輸入的用戶名是: {this.state.username} <br/>
你輸入的密碼是: {this.state.password}
</p>
</div>
);
}
}
ReactDOM.render(
<Reservation />,
document.getElementById('root')
)
</script>
十三、獲取真實的DOM節點
通過ref可以獲取真實dom節點,需要確保節點已經掛載
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.refs.myTextInput.focus();
}
render() {
return (
<div>
<input type="text" ref="myTextInput" />
<input type="button" value="獲取焦點" onClick={this.handleClick} />
</div>
)
}
}
ReactDOM.render(
<MyComponent />,
document.getElementById('root')
);
</script>
十四、this.props.children
this.props 對象的屬性與組件的屬性一一對應,但是有一個例外,就是 this.props.children 屬性。它表示組件的所有子節點
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root">
</div>
</body>
</html>
<script type="text/babel">
class NotesList extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
}
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.body
);
</script>
demo地址:
參考:
React 入門實例教程 http://www.ruanyifeng.com/blog/2015/03/react.html
React中文文檔 https://react.docschina.org/docs/hello-world.html