1. npx creact-react-app 出来没有webpack文件
用npm run eject命令。
react-scripts 是 create-react-app 的一个核心包,一些脚本和工具的默认配置都集成在里面,而命令执行后会将封装在 create-react-app 中的配置全部反编译到当前项目,这样就能完全取得 webpack 文件的控制权。但该操作时不可逆的,所以如果想回去,只有重新npm creat-xxxx。
执行npm run eject命令可能会出现一个报错:如下
error.png
解决方法:
git init
git add .
git commit -m 'init'
2.路由跳转传参方式
在跳转路由的链接中通过‘?’传递参数
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
</Switch>
//link方式跳转
<Link to="/about?msg='url参数'">去关于我的页面 url传递参数</Link>
//js方式跳转
this.props.history.push({ pathname:"/about?msg='url参数'"});
//about中获取参数
console.log(this.props.location)
//{pathname: "/about", search: "?msg='url参数'", hash: "", state: undefined}
优缺点:参数比较灵活,参数直接在url中暴露,刷新路由页面时传递参数依然可以正常访问。缺点是还需要js通过search中解析类似getParameter(msg)方式获取真实值
通过:id方式
<Route exact path="/about/:msg" component={About} />
//link方式
<Link to="/about/url参数">去关于我的页面 路由配置传递参数</Link>
//js方式跳转
this.props.history.push({ pathname:"/about/'url参数'"});
//about中获取参数
console.log(this.props.match.params.msg)
//url参数
优缺点:参数比较灵活,参数直接在url中暴露,刷新路由页面时传递参数依然可以正常访问。但每增加一个参数需要在Route中注册一个,而且顺序需要一致。
其他query(自定义属性)和state
// query 传递参数
this.props.history.push({
pathname: '/about',
query: {
msg: 'msg by query'
}
});
// state 传递参数
this.props.history.push({
pathname: '/about',
state: {
msg: 'msg by state'
}
});
// query 接受参数
console.log(this.props.location.query.msg)//msg by query
// state 接受参数
console.log(this.props.location.state.msg)//msg by state
优缺点:参数灵活,不用给Route额外的配置,参数是加密的,不暴露在url上。
3. React-router V4 中的BrowserRouter和HashRouter
HashRouter
它使用URL的哈希部分(即window.location.hash)来保持页面的UI与URL同步。
重要说明:哈希历史记录不支持location.key或location.state。
BrowserRouter
使用HTML5历史API( pushState,replaceState和popstate事件),让页面的UI同步与URL
可以查看官网api了解更多。
区别:1.URL的不同
HashRouter使用URL(即window.location.hash)的哈希部分来保持UI与URL同步的。哈希历史记录不支持location.key和location.state 详情查看history 用来支持旧版浏览器,官方不建议使用。简单来说,就是不需要服务器端渲染,靠浏览器的# 来区分path。
BrowserRouter使用HTML5 history API,保证UI界面和URL保存同步。要求服务器端对不同URL返回不同的HTML。
例如,有两个页面Home和About,如果用HashRouter,两个URL就是这样,因为#后面的部分不会发给服务器,所以服务器只需要应对 / 路径的请求就好
https://xxxxxx.com/#/home
https://xxxx.com/#/about
如果用BrowserRouter,两个URL就是这样,服务器不得不对 /home 和 /about 做不同请求
https://xxxxxx.com/home
https://xxxx.com/about
2.路由跳转传递参数和刷新页面数据丢失
当点击触发js跳转到about,然后回退到上一页,再点击下一页到about页面。参数通过state传递
//about组件
class About extends Component {
constructor(props) {
super(props);
}
render() {
console.log(this.props.location);
return (
<div className="demo">
我是一个路由跳转后的子页面
<br />
<div>
参数:{JSON.stringify(this.props.location)}
</div>
<Link to="/">回首页</Link>
</div>
);
}
}
//通过js跳转
this.props.history.push({
pathname: '/about',
state: {
msg: 'msg by state'
}
});
//HashRouter结果
//第一次进入页面打印结果
{"pathname":"/about","state":{"msg":"msg by state"},"search":"","hash":""}
//刷新页面或者后退再前进
{"pathname":"/about","search":"","hash":""}
//BowserRouter结果
//第一次进入页面打印结果
{"pathname":"/about","state":{"msg":"msg by state"},"search":"","hash":"","key":"1m6gz4"}
//刷新页面或者后退再前进
{"pathname":"/about","state":{"msg":"msg by state"},"search":"","hash":"","key":"1m6gz4"}
当我们通过state传递参数的时候,因为hashRouter没有使用html5中history的api,无法从历史记录中获取到key和state值,所以当刷新路由后state值会丢失导致页面显示异常。
总结:实现路由页面页面刷新数据不丢失的方案
BorwserRouter有三种方式(url传值,路由参数传值,以及state)
HashRouter有两种方式(url传值,路由参数传值)
本地缓存或者状态管理方案
4. 生命周期
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor (props){
super(props)
this.state = {
data: 'old state'
}
console.log('c初始化数据constructor')
}
//组件将要加载执行
componentWillMount () {
console.log('componentWillMount')
}
//组件挂载(加载)完成
componentDidMount () {
console.log('componentDidMount')
}
//将要接受父组件传来的props
componentWillReceiveProps () {
console.log('componentWillReceiveProps')
}
//子组件是否更新
shouldComponentUpdate () {
console.log('shouldComponentUpdate')
return true
}
//组件将要更新
componentWillUpdate () {
console.log('componentWillUpdate')
}
//组件更新完成
componentDidUpdate () {
console.log('componentDidUpdate')
}
//组件即将销毁
componentWillUnmount () {
console.log('componentWillUnmount')
}
//处理点击事件
handelClick(){
console.log('更新数据')
this.setState({
data:'new state'
})
}
render() {
console.log('render')
return (
<div>
<div>app</div>
<button onClick={()=>{this.handelClick()}}>更新组件</button>
</div>
);
}
}
export default App;
打印.png
5.@withRouter
withRouter可以包装任何自定义组件,将react-router 的 history,location,match 三个对象传入。
使用@需要install 两个依赖,并在package.json的babel中配置
下载依赖与配置.png
6.react定义组件的三种方式和区别
- 函数式定义的无状态组件
- es5原生方式React.createClass定义的组件
- es6形式的extends React.Component定义的组件
参考https://www.cnblogs.com/wonyun/p/5930333.html
补充:无状态函数式组件写法
const HelloWorld = (props) => (
<h1>{props.text}</h1>
)
7. react状态管理Mobx vs Redux
参考:https://blog.csdn.net/vhwfr2u02q/article/details/79395072
网友评论