這是我參與8月更文挑戰的第2天,活動詳情查看:8月更文挑戰css
本文做爲本人學習總結之用,同時分享給你們,適合入門的react小白
由於我的技術有限,若是有發現錯誤或存在疑問之處,歡迎指出或指點!不勝感謝!html
第一步,全局安裝:npm i -g create-react-app
前端
第二步,切換到想創項目的目錄,使用命令:react
create-react-app hello-react
web
yarn create react-app hello-react
ajax
第三步,進入項目文件夾:cd hello-react
npm
第四步,啓動項目:npm start
或者yarn start
編程
1.第一步:建立代理配置文件bootstrap
在src下建立配置文件:src/setupProxy.js後端
2.編寫setupProxy.js配置具體代理規則:
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(
proxy('/api1', { //api1是須要轉發的請求(全部帶有/api1前綴的請求都會轉發給5000)
target: 'http://localhost:5000', //配置轉發目標地址(能返回數據的服務器地址)
changeOrigin: true, //控制服務器接收到的請求頭中host字段的值
/* changeOrigin設置爲true時,服務器收到的請求頭中的host爲:localhost:5000 changeOrigin設置爲false時,服務器收到的請求頭中的host爲:localhost:3000 changeOrigin默認值爲false,但咱們通常將changeOrigin值設爲true */
pathRewrite: {'^/api1': ''} //去除請求前綴,保證交給後臺服務器的是正常請求地址(必須配置)
}),
proxy('/api2', {
target: 'http://localhost:5001',
changeOrigin: true,
pathRewrite: {'^/api2': ''}
})
)
}
複製代碼
說明:
路由的概念來源於服務端,在服務端中路由描述的是 URL 與處理函數之間的映射關係。
在 Web 前端單頁應用 SPA中,路由描述的是 URL 與 UI 之間的映射關係,這種映射是單向的,即 URL 變化引發 UI 更新(無需刷新頁面)。
<a>
標籤改變 URL、經過window.location改變URL,這幾種狀況改變 URL 都會觸發 hashchange 事件優勢:優勢: 實現簡單,兼容性好(兼容到 ie8) 絕大多數前端框架均提供了給予 hash 的路由實現 不須要服務器端進行任何設置和開發 除了資源加載和 ajax 請求之外,不會發起其餘請求
缺點: 對於部分須要重定向的操做,後端沒法獲取 hash 部份內容,致使後臺無 法取得 url 中的數據,典型的例子就是微信公衆號的 oauth 驗證 服務器端沒法準確跟蹤前端路由信息 對於須要錨點功能的需求會與目前路由機制衝突
history 提供了 pushState 和 replaceState 兩個方法,這兩個方法改變 URL 的 path 部分不會引發頁面刷新
history 提供相似 hashchange 事件的 popstate 事件,但 popstate 事件有些不一樣:經過瀏覽器前進後退改變 URL 時會觸發 popstate 事件,經過pushState/replaceState或<a>
標籤改變 URL 不會觸發 popstate 事件。好在咱們能夠攔截 pushState/replaceState的調用和<a>
標籤的點擊事件來檢測 URL 變化,因此監聽 URL 變化能夠實現,只是沒有 hashchange 那麼方便
優勢 :對於重定向過程當中不會丟失 url 中的參數。後端能夠拿到這部分數據。絕大多數前段框架均提供了 history 模式的路由實現。後端能夠準確跟蹤路由信息 可使用 history.state 來獲取當前 url 對應的狀態信息
缺點:兼容性不如 hash 路由(只兼容到 IE10) 須要後端支持,每次返回 html 文檔
hash | history |
---|---|
只修改#後面內容 | 能夠設置同源下任意的URL |
新值不能與舊值相同,同樣的不會觸發動做將記錄添加到棧中 | 新舊值能夠相同,pushSate該添加的會添加到棧中 |
對服務器無需改動 | 刷新時,若服務器沒有響應數據或資源,會404。須要對服務器作一些改造,對不一樣的路由進行相應的設置。 |
即不會發送請求 | 會向服務器發送請求,避免404服務器應該作處理。當匹配不到資源時,應返回同一個html頁面。 |
安裝:yarn add react-router-dom
1.導航區爲Link標籤
<Link className="list-group-item" to="/about">About</Link>
2.展現區寫Route標籤進行路徑的匹配
<Route path="/about" component={About}/>
3.<App>的最外側包裹了一個<BrowserRouter>或<HashRouter>
//index.js
ReactDOM.render(
<BrowserRouter> <App/> </BrowserRouter>,
document.getElementById('root')
)
複製代碼
跟link同樣的寫法
NavLink能夠實現路由連接的高亮,經過activeClassName指定樣式名
<NavLink activeClassName="atguigu" className="list-group-item" to="/about">About</NavLink>
//封裝組件
//props中有children children正好是NavLink的屬性名顯示文字內容
<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
//調用時
<MyNavLink to="/about">About</MyNavLink>
複製代碼
1.一般狀況下,path和component是一一對應的關係。
2.Switch能夠提升路由匹配效率(單一匹配)。 找到以後再也不繼續找尋
{/* 註冊路由 */}
用Switch包裹以後僅出現Home組件
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Route path="/home" component={Test}/>
</Switch>
複製代碼
通常寫在全部路由註冊的最下方,當全部路由都沒法匹配時,跳轉到Redirect指定的路由(重定向)
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Redirect to="/about"/>
</Switch>
複製代碼
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="stylesheet" href="/css/bootstrap.css"> ReactDOM.render( <HashRouter> <App/> </HashRouter>, document.getElementById('root') ) 複製代碼
<Route exact={true} path="/about" component={About}/>
或者簡寫
<Route exact path="/about" component={About}/>
//子路由的寫法
<Switch>
<Route path="/home/news" component={News}/>
<Route path="/home/message" component={Message}/>
<Redirect to="/home/news"/>
</Switch>
複製代碼
params參數
路由連接(攜帶參數):<Link to='/demo/test/tom/18'}>詳情</Link>
註冊路由(聲明接收):<Route path="/demo/test/:name/:age" component={Test}/>
接收參數:this.props.match.params
search參數
路由連接(攜帶參數):<Link to='/demo/test?name=tom&age=18'}>詳情</Link>
註冊路由(無需聲明,正常註冊便可):<Route path="/demo/test" component={Test}/>
接收參數:this.props.location.search
備註:獲取到的search是urlencoded編碼字符串,須要藉助querystring解析
state參數
路由連接(攜帶參數):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>詳情</Link>
註冊路由(無需聲明,正常註冊便可):<Route path="/demo/test" component={Test}/>
接收參數:this.props.location.state
備註:刷新也能夠保留住參數
messageArr.map((msgObj)=>{
return (
<li key={msgObj.id}> {/* 向路由組件傳遞params參數 */} <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> {/* 向路由組件傳遞search參數 */} <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> {/* 向路由組件傳遞state參數 */} <Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link> </li>
)
})
{/* 聲明接收params參數 */}
<Route path="/home/message/detail/:id/:title" component={Detail}/>
{/* search參數無需聲明接收,正常註冊路由便可 */}
<Route path="/home/message/detail" component={Detail}/>
{/* state參數無需聲明接收,正常註冊路由便可 */}
<Route path="/home/message/detail" component={Detail}/>
子組件
import qs from 'querystring'
export default class Detail extends Component {
render() {
// 接收params參數
const {id,title} = this.props.match.params
// 接收search參數
const {search} = this.props.location
const {id,title} = qs.parse(search.slice(1))
// 接收state參數
const {id,title} = this.props.location.state || {}
const findResult = DetailData.find((detailObj)=>{
return detailObj.id === id
}) || {}
return (
<ul> <li>ID:{id}</li> <li>TITLE:{title}</li> <li>CONTENT:{findResult.content}</li> </ul>
)
}
}
複製代碼
//藉助this.prosp.history對象上的API對操做路由跳轉、前進、後退
this.prosp.history.push() //push查看
//push跳轉+攜帶params參數
this.props.history.push(`/home/message/detail/${id}/${title}`)
//push跳轉+攜帶search參數
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)
//push跳轉+攜帶state參數
this.props.history.push(`/home/message/detail`,{id,title})
this.prosp.history.replace() //replace查看
//replace跳轉+攜帶params參數
this.props.history.replace(`/home/message/detail/${id}/${title}`)
//replace跳轉+攜帶search參數
this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
//replace跳轉+攜帶state參數
this.props.history.replace(`/home/message/detail`,{id,title})
this.prosp.history.goBack() //回退
this.prosp.history.goForward() //前進
this.prosp.history.go(n) //負爲退 正爲進
複製代碼
例如:localhost:3000/demo/test
例如:localhost:3000/#/demo/test