
前言:
这里记录我在工作或学习中用到的小技巧
1、获取指定日期的上一周或上上周(moment.js)
比如获取2019-01-01
的上一周的起始日期或者是上N
周的起始日期
<script src="moment.js"></script>
<script>
let date='2019-01-01'
let when=-1 //-1表示上一周,-2表示上上周,0 表示本周。
//获取 date 所在的第几周
const weeknumber=moment(date).isoWeek() //1
const startDate=moment(date)
.week(+weeknumber+when) //.week(0)
.isoWeekday(1) //获取所在周的周一
.format('YYYY-MM-DD'); // 2018-12-24
const endDate=moment(date)
.week(+weeknumber+when)
.isoWeekday(7) //获取所在周的周日
.format('YYYY-MM-DD'); // 2018-12-30
</script>
注意!如果你截取了 year 来获取某周日期的话,会出错!
获取2018-12-31
所在周的起始日期
错误示范:
let date='2018-12-31'
let when=0 //本周
const weeknumber=moment(date).isoWeek()
const dateArr=date.split('-')
const startDate=moment()
.year(+dateArr[0])
.week(+weeknumber+when)
.isoWeekday(1)
.format('YYYY-MM-DD'); // 2018-01-01
const endDate=moment()
.year(+dateArr[0])
.week(+weeknumber+when)
.isoWeekday(7)
.format('YYYY-MM-DD'); // 2018-01-07
可以看到:2018-12-31
所在周是第一周,但你想当然以为所在年是2018
年,导致获取的是2018
年的第一周的起始日期2018-01-01~2018-01-07
!
正确示范:
let date='2018-12-31'
let when=0
const weeknumber=moment(date).isoWeek()
const startDate=moment(date)
.week(+weeknumber+when)
.isoWeekday(1)
.format('YYYY-MM-DD'); //2018-12-31
const endDate=moment(date)
.week(+weeknumber+when)
.isoWeekday(7)
.format('YYYY-MM-DD'); //2019-01-06
2018-12-31
所在周的起始日期为2018-12-31~2019-01-06
2、antd
的<Tooltip>
组件的title
内容换行显示
正确示范:
<Tooltip
title={"aaa\r\nbbb\r\nccc"}
overlayStyle={{whiteSpace:'pre-wrap'}}
>
<span>Tooltip will show on mouse enter.</span>
</Tooltip>

错误示范:
<Tooltip
//或者是 title={"aaa\r\nbbb\r\nccc"}
title={"aaa\nbbb\nccc"}
>
<span>Tooltip will show on mouse enter.</span>
</Tooltip>

注意:
(1)只写\n
无效,必须写\r\n
(2)overlayStyle
中的属性必须有whiteSpace:'pre-wrap'
3、React更新的方式有三种:
(1)ReactDOM.render() || hydrate(ReactDOMServer渲染)
(2)setState
(3)forceUpdate
详情请参考:
React源码解析之ReactDOM.render()
React源码解析之setState和forceUpdate
4、func.bind()
func.bind(xx)
的意思是func
里的this
绑定的是xx
,
也就是说是xx
调用func
方法:
function func(){
console.log(this.name)
}
const xx={name:"chen"}
func.bind(xx)(); //chen
注意:
func.bind(xx)
这仅仅是绑定,它会返回一个新函数,而不是调用:
function func(){
console.log(this.name)
}
const xx={name:"chen"}
const newFunc=func.bind(xx)
newFunc(); //chen
//newFunc();
func() //这时是 windows 在调用,因为 没有使用.bind()后绑定返回的新函数
5、超过的字显示成三点,但鼠标悬浮会显示隐藏内容
<span
title="鼠标悬浮,显示隐藏内容"
style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width: 128px;display: inline-block;">
鼠标悬浮,显示隐藏内容
</span>

6、setState
造成死循环的常见两种情况:
(1) 在 render() 中无条件调用 setState()
注意:
有条件调用 setState() 的话,是可以放在 render() 中的
render(){
if(xxx){
this.setState({ yyy })
}
}
(2) 如下图,在 shouldComponentUpdate() 和 componentWillUpdate() 中调用 setState()

7、为什么不直接从 JSX 直接渲染构造 DOM 结构,而是要经过中间一层?(具体看下图)

① 当拿到一个 JSX 的 React 对象时,不一定会将其渲染到 浏览器页面 上,可能是 canvas 或 react-native 上,然后再由 canvans 渲染到页面上
② 当数据变化,需要更新组件时,用 diff 算法去操作 JSX 对象,而不是直接操作,这样尽量减少浏览器重排,极大优化性能
8、为什么React 的 props 不可修改?
因为 React 希望组件在输入「确定的 props」后,能够输出 「确定的 UI」 ,
如果 props 在渲染的过程中被修改,会导致该组件的显示和行为不可预测
9、React 点击 A 页面跳转到 B页面并滚动到指定位置
render(){
const flag = window.localStorage.getItem(' flag');
if (flag === 'true' && $('html, body') && $('#pageB')[0]) {
// 滚动到指定位置
$('html, body').animate(
{
scrollTop: 3200,
},
1000
);
window.localStorage.setItem('flag', 'false');
}
}
注意:
需要设置一个 flag 保存在 localStroage 中,作为页面滚动的tirgger
如果是跨域的话,可以通过router
,判断前一个 router 是否是 页面 A 的 router
10、什么是高阶组件?(HOC — Higher-Oder Components)
项目中的封装的可复用的组件不是高阶组件,因为它是一个组件,而不是函数
ant-design-Pro
中的connect
(也就是封装的 redux)是高阶组件:
将需要的数据传给组件 componentA
export default connect(({ haha, }) => ({
hahaData: haha.hahaData,
}))(componentA);
高阶组件是一个函数,而不是组件!:
export default (WrappedComponent)=>{
class NewComponet extends Component{
//做自定义的逻辑
render(){
return <WrappedComponent />
}
}
return NewComponent
}
HOC 与普通组件的区别:
普通组件是将 props 转为 UI
高阶组件是将 组件转换为另一个组件

高阶组件的设计模式是装饰者模式
什么是装饰者模式?
https://segmentfault.com/p/1210000009968000/read

(完)
网友评论