这是我参与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