React 基本原理
- 初始化显示界面
创建虚拟DOM树
渲染到 原生 DOM 树
绘制界面显示
- 更新界面
setState() 更新状态机
重新创建虚拟 DOM 树
新/旧树比较差异 (执行一次 DOM Diff 算法)
更新差异并渲染到对应 原生 DOM (捕获差异,并渲染)
局部界面重绘
基于 react 的 ajax 异步显示效果 (比如: 先显示 loading,等有了数据之后再显示正文)
测试接口: https://api.github.com/search/repositories?q=r&sort=stars
-
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title></title> <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/> <style rel="stylesheet" type="text/css"> .unSelectedAble { /* 内容不可以被选中 */ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } * { padding: 0; margin: 0; } a { text-decoration: none; } ul, ol { list-style: none; } input { outline: none; } img { display: block; } html, body { height: 100%; /* overflow: hidden; */ } /**** Start ****/ html { /* touch-action: none; */ } #wrap { width: 100%; min-height: 100%; background-color: #b3ccaf; } #content { width: 100%; padding-bottom: 50px; padding-top: 50px; padding-left: 50px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; font-size: 14px; background-color: #b3ccaf; } #footer { width: 100%; height: 50px; margin-top: -50px; color: #b3ccaf; background-color: #162454; text-align: center; line-height: 50px; } button { height: 36px; margin: 20px; padding: 4px; color: #000; font-size: 18px; background-color: #94b5b2; border: 0 none; border-radius: 6px; } input { padding: 6px; font-size: 18px; margin: 0 2px; background-color: #b76f59; border: 0 none; } </style> </head> <body class="unSelectedAble"> <!-- 模拟屏幕区域 --> <div id="wrap"> <!-- 内容区域 --> <div id="content"> </div> </div> <!-- 底部区域 --> <div id="footer"> Copyright ©2019 耶梦加德 </div> <!-- javascript 代码 --> <script src="https://cdn.bootcss.com/react/16.7.0/umd/react.development.js"></script> <script src="https://cdn.bootcss.com/react-dom/16.7.0/umd/react-dom.development.js"></script> <script src="https://cdn.bootcss.com/prop-types/15.6.2/prop-types.js"></script> <script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.js"></script> <script type="text/babel"> class MostPopularReponsitory extends React.Component{ state = { keyword: "", repoUrl: "", repoName: "", points: [".", ".", "."], result:"What do u wanna search ?" }; handleInput = ()=>{ const keyword = this.refs.newKeyword.value; this.setState({ keyword }); }; handleSearch = ()=>{ const {keyword, points} = this.state; if(keyword === ""){ return ; } this.refs.newKeyword.value = ""; this.setState({ keyword: "", result: <p>Searching{points.map(each=>each)}</p> }); const url = `https://api.github.com/search/repositories?q=${keyword}&sort=stars`; axios.get(url).then(response=>{ const {name:repoName, html_url:repoUrl} = response.data.items[0]; this.setState({ repoName, repoUrl }); this.setState({ result: <span>The most popular Git Reponsitory about {keyword} is <a href={repoUrl} target="_blank"> {repoName}</a> </span> }); }).catch(err=>console.log(err?"Search error: "+err:"Search From: "+url)); }; render(){ const {result} = this.state; return ( <div> <label> <input type="text" ref="newKeyword" onBlur={this.handleInput}/> </label> <button onClick={this.handleSearch}>Tips</button> <h2>{result}</h2> </div> ) } } ReactDOM.render(<MostPopularReponsitory/>, document.getElementById("content")); </script> </body> </html>