//引入相關庫 <script type="text/javascript" src="../js/react.development.js"></script> <script type="text/javascript" src="../js/react-dom.development.js"></script> <script type="text/javascript" src="../js/babel.min.js"></script> <script type="text/babel"> //必須聲明babel // 建立虛擬DOM元素 const vDom = <h1>Hello React</h1> // 千萬不要加引號 // 渲染虛擬DOM到頁面真實DOM容器中 ReactDOM.render(vDom, document.getElementById('test')) </script>
特別
的通常js對象var element = React.createElement('h1', {id:'myTitle'},'hello')
<body> <div id="test"></div> </body> <script type="text/babel"> // 建立虛擬DOM對象 const vDom1 = React.createElement('p',{id: 'myId1', className: 'myClass1'}, '珂朵莉',vDom3); // 將虛擬DOM對象插入到頁面的指定容器中,渲染虛擬DOM(元素) ReactDOM.render(vDom1, document.getElementById('test1')); //方法一 //方法二 const id = 'myId2'; const content = '我永遠喜歡珂朵莉'; const vDom3 = React.createElement('span', {}, 'daisiki'); const vDom2 = <div><h2 id={id } className="myClass2">{content}</h2>{vDom3}</div> // 將虛擬DOM對象插入到頁面的指定容器中 ReactDOM.render(vDom2, document.getElementById('test2')); const list = ['1', '2', '3', '4']; ReactDOM.render( <ul> { list.map(( item,index) => <li key={index}>{item}</li> ) } </ul> ,document.getElementById('test3')) <script>
1)全稱: JavaScript XML 2)react定義的一種相似於XML的JS擴展語法: XML+JS 3)做用: 用來建立react虛擬DOM(元素)對象 a.var ele = <h1>Hello JSX!</h1> b.注意1: 它不是字符串, 也不是HTML/XML標籤 c.注意2: 它最終產生的就是一個JS對象 4)標籤名任意: HTML標籤或其它標籤 5)標籤屬性任意: HTML標籤屬性或其它 6)基本語法規則 a.遇到 <開頭的代碼, 以標籤的語法解析: html同名標籤轉換爲html同名元素, 其它標籤須要特別解析 b.遇到以 { 開頭的代碼,以JS語法解析: 標籤中的js代碼必須用{ }包含, //待定:* if/for循環 不能用 7)babel.js的做用 a.瀏覽器不能直接解析JSX代碼, 須要babel轉譯爲純JS的代碼才能運行 b.只要用了JSX,都要加上type="text/babel", 聲明須要babel來處理
定義組件(2種方式)javascript
/*方式1: 工廠函數組件(簡單組件)*/ function MyComponent () { return <h2>工廠函數組件(簡單組件)</h2> } /*方式2: ES6類組件(複雜組件)*/ class MyComponent2 extends React.Component { render () { console.log(this) // MyComponent2的實例對象 return <h2>ES6類組件(複雜組件)</h2> } }
渲染組件標籤html
ReactDOM.render(<MyComponent />, document.getElementById('example1'))
虛擬DOM元素必須有結束標籤前端
初始化java
name: 'Mary'}node
constructor (props) { super(props) console.log(props) // 查看全部屬性 }
組件內的標籤均可以定義ref屬性來標識本身, 用來獲取DOM元素
在組件中能夠經過this.msgInput來獲得對應的真實DOM元素react
a. <input type="text" ref={this.createRef}/> (推薦使用) b. <input type="text" ref={input => this.funcRef = input}/> c. <input type="text" ref="stringRef" /> (即將廢棄) d. 回調函數在組件初始化渲染完或卸載時自動調用
做用: 經過ref獲取組件內容特定標籤對象, 進行讀取其相關數據webpack
1.<input type="text" ref={this.createRef}/> 2.<input type="text" ref={(input) => this.funcRef = input}/> 3.<input type="text" ref="stringRef"/> constructor(props) { super(props); this.createRef = React.createRef(); } // 獲取input標籤的值 1. this.createRef.current 2. console.log(this.funcRef); 3. console.log(this.refs.stringRef);
經過onXxx屬性指定組件的事件處理函數(注意大小寫)ios
經過event.target獲得發生事件的DOM元素對象git
<input onFocus={this.handleClick}/> handleFocus(event) { event.target //返回input對象 }
2)在組件類中自定義的方法中this爲undefined程序員
React組件中函數this指向規則
1.拆分組件:根據頁面功能拆分 APP AddTodo TodoList 2.實現靜態組件 先實現大的組件(最外層的),再實現裏面的組件 先有一個基本的顯示效果 3.實現動態組件 1.需不須要定義狀態數據? 看頁面是否有變化,有變化就要定義狀態數據 2.狀態數據定義在哪裏? APP 若是數據是單個組件須要,就定義在單個組件中 若是數據是多個組件須要,就定義在公共的父組件中,也就是引用了那幾個多組件的父組件 3.狀態數據定義爲何? 定義成對象、數組、基本數據類型。 方便插入數據和遍歷展現,因此用數組 4.子組件如何操做父組件的數據 父組件定義操做數據的方法(數據再哪,操做數據的方法就在在哪) 父組件將操做數據的方法傳給子組件,子組件調用就能修改父組件的數據
組件的三個生命週期狀態:
React 爲每一個狀態都提供了勾子(hook)函數
生命週期流程:
第一次初始化渲染顯示: ReactDOM.render()
每次更新state: this.setSate()
移除組件: ReactDOM.unmountComponentAtNode(containerDom)
constructor()` * 初始化state * 修改函數的this指向 * 只會執行一次 static getDerivedStateFromProps(nextProps, prevState)` * 通常不用 * 使組件可以根據props的更改來更新其內部狀態 render()` * 渲染組件 componentDidMount()` * 發送ajax請求 * 執行異步任務 * 只會執行一次 shouldComponentUpdate(nextProps, nextState)` * react性能優化,減小沒必要要的render getSnapshotBeforeUpdate(prevProps, prevState)` * 通常不用 * 能夠在渲染以前獲得DOM對象從而獲取一些信息 componentDidUpdate(prevProps, prevState, snapshot)` * 更新組件完成時對DOM進行操做 * 發送ajax請求(注意不要陷入死循環) componentWillUnmount()` * 清除定時器,收尾工做等
xxx腳手架: 用來幫助程序員快速建立一個基於xxx庫的模板項目
npm install -g create-react-app //全局安裝create-react-app create-react-app hello-react //建立一個項目名稱爲hello-react的腳手架 npm start //必須在hello-react文件目錄下運行
ReactNews |--node_modules---第三方依賴模塊文件夾 |--public |-- index.html-----------------主頁面 |--src------------源碼文件夾 |--components-----------------react組件 |--index.js-------------------應用入口js |--.gitignore------git版本管制忽略的配置 |--package.json----應用包配置文件 |--README.md-------應用描述說明的readme文件
axios: 輕量級, 建議使用
fetch: 原生函數, 但老版本瀏覽器不支持
componentDidMount(){ //發送Ajax請求 /* axios.get('https://api.github.com/search/repositories?q=r&sort=stars') //axios.get('/user', {params: {q:r,sort:stars}}) //axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'}) .then(response => { const {name, html_url} = response.data.items[0]; this.setState({ name,url: html_url}) }) .catch(err =>{ console.log(err); })*/ fetch('https://api.github.com/search/repositories?q=v&sort=stars') //get: fetch(url) post: fetch(url, {method: "POST" body:JSON.stringify(data),}) .then(res => res.json()) .then(response =>{ console.log(response); const {name, html_url} = response.items[0]; this.setState({name,url: html_url }) }) .catch(err =>{ console.log(err); }) }
後臺路由: node服務器端路由, value是function, 用來處理客戶端提交的請求並返回一個響應數據
前臺路由: 瀏覽器端路由, value是component(組件), 當請求的是路由path時, 瀏覽器端前沒有發送http請求, 但界面會更新顯示對應的組件
* 前端路由 * 不須要發送請求 * 不會刷新整個頁面,局部更新 * 會修改url地址和瀏覽器歷史記錄 * value是component * 後端路由 * 會發送請求 * 會刷新整個頁面 * 會修改url地址和瀏覽器歷史記錄 * value是callback
使用前端路由的做用:
history庫
a. 網址: https://github.com/ReactTraining/history b. 管理瀏覽器會話歷史(history)的工具庫 c. 包裝的是原生BOM中window.history和window.location.hash
history API
a. History.createBrowserHistory(): 獲得封裝window.history的管理對象 b. History.createHashHistory(): 獲得封裝window.location.hash的管理對象 c. history.push(): 添加一個新的歷史記錄 d. history.replace(): 用一個新的歷史記錄替換當前的記錄 e. history.goBack(): 回退到上一個歷史記錄 f. history.goForword(): 前進到下一個歷史記錄 g. history.listen(function(location){}): 監視歷史記錄的變化
組件
1) <BrowserRouter> browserHistory 是使用 React-Router 的應用推薦的 history方案。 它使用瀏覽器中的 History API 用於處理 URL,建立一個像example.com/list/123這樣真實的 URL <BrowserRouter><App /></BrowserRouter> 2) <HashRouter> 3) <Route> <Route path="/about" component={About}/> <Route path="/home/message/:id" component={MessageDetail}/> 一旦url變爲path對應的值,就加載component中的組件進行顯示 4) <Redirect> <Redirect to="/about"/> 什麼路徑都匹配,一旦匹配上就跳轉到指定網址,與Switch配合使用 5) <Link> 只修改url的地址,不會發送請求 <Link to="/home">珂朵莉</Link> 6) <NavLink> 只修改url的地址,不會發送請求,而且多了一個class:active export default function MyNavLink(props) { return <NavLink {...props} activeClassName='activeClass'/> } <MyNavLink to="/about">About</MyNavLink> 7) <Switch> 切換顯示(針對內部組件 - 子組件) --> 從上到下匹配,一旦有一個匹配上,其餘就不看了 <Switch> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Redirect to="/about"/> </Switch>
路由組件:經過Route組件加載的組件(import { withRouter } from 'react-router-dom')