1.父级传参到子级,可以通过...扩展运算符来传递
const settings = {
dots: true, //下面的点
arrow: false, //走马灯两边不会出现箭头
slidesToShow: 1, // 显示一屏
swipeToSlide: true, //通过拨动触发每一屏的变化
autoplay: true
};
<Slider test="test" {...settings}></Slider>
在Slider组件下,用 this.props 方法可查看传给子级的所有属性(前提是谷歌浏览器有装react的插件,可以查看元素)
props
arrow:false
autoplay: true
dots: true
…… ……
2.mapDispatchToProps中return的bindActionCreators里的方法
例子:loadDiscounts 和 loadLikes 在 homeActions 里面
export const actions = {
loadLikes: ()=>{
return (dispatch, getState) => {
const {pageCount} = getState().home.likes;
const rowIndex = 1
const endpoint = url.getProductList();
return dispatch({type: "……" ,endpoint,……});
}
},
loadDiscounts: () => {
return (dispatch, getState) => {
………………
};
}
}
import { bindActionCreators } from "redux";
import { actions as homeActions } from "…………";
componentDidMount() {
this.props.homeActions.loadDiscounts();
}
fetchMoreLikes = () => {
this.props.homeActions.loadLikes()
}
const mapDispatchToProps = dispatch => {
return {
homeActions: bindActionCreators(homeActions, dispatch)
};
};
export default connect(
null,
mapDispatchToProps
)(Home);
3.处理屏幕滚动事件,实现加载更多的效果
- 这是个组件滚动content,独自一个组件
handleScroll = () => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 滚动多少距离
const screenHeight = document.documentElement.clientHeight; // 当前页面窗口可视区范围高度 包括padding但不包括border、水平滚动条、margin的元素的高度。对于inline的元素这个属性一直是0,单位px
const likeListTop = this.myRef.current.offsetTop; // 当前组件到页面顶部的距离
const likeListHeight = this.myRef.current.offsetHeight; // 包括padding、border、水平滚动条,但不包括margin的元素的高度 对于inline的元素这个属性一直是0,单位px
if(scrollTop + 60 >= likeListHeight + likeListTop - screenHeight){
this.props.fetchData();
}
}
render(){
return (
<div ref={this.myRef}></div>
)
}
- 滚动content没有抽离成独自一个组件
// 处理屏幕滚动事件,实现加载更多的效果
handleScroll() {
if (this.state.menuIndex != 0) return;
//滚动条滚动距离
const scrollTop = this.myRef.current.scrollTop;
//文档内容实际高度(包括超出视窗的溢出部分)
const scrollHeight = this.myRef.current.scrollHeight;
//窗口可视范围高度
const screenHeight = this.myRef.current.clientHeight;
if (screenHeight + scrollTop + 200 >= scrollHeight) {
this.onLoadMore()
}
}
render(){
return (
<div>
<div/>
……
<div ref={this.myRef}>……</div>
…… ……
</div>
)
}
4.redux-actions 的用法
[官方文档]redux-actions.js.org/introductio…) createAction用来创建动作创建器的函数
// action.js
import { createAction } from "redux-actions"
const increment = createAction("INCREMENT");
increment() 调用返回 { type: 'INCREMENT' }
increment("100") 调用返回 { type: 'INCREMENT', payload: 100 }
createAction(type, payloadCreator, metaCreator)
const updateAdminUser = createAction(
'UPDATE_ADMIN_USER',
updates => updates,
() => ({ admin: true })
);
updateAdminUser({ name: 'Foo' });
// {
// type: 'UPDATE_ADMIN_USER',
// payload: { name: 'Foo' },
// meta: { admin: true },
// }
handleActions函数是用来处理多个动作 (handleAction 也可以不过只能单个)
// reducer.js
import {handleActions} from 'redux-actions';
import {INCREMENT} from './action'
const reducer = handleActions({
INCREMENT: (state, action) => ({
counter: state.counter + action.payload
}),
DECREMENT: (state, action) => ({
counter: state.counter - action.payload
})
},{ counter: 0 });
用法:
handleActions(reducerMap, defaultState) => reducerMap中key就是动作名, value就是reducer
5.React中获取DOM节点的方式
- React.createRef()
this.state={
this.cont = React.createRef();
}
componentDidMount() {
this.cont.current.addEventListener("scroll", this.handleScroll);
// this.cont.current=>就是Dom节点
}
render() {
<div ref={this.cont}>…… ……</div>
}
// `scroll` 不知是否可以用 `touchmove` 代替?
- ref={ } 通过一个函数返回
componentDidMount() {
this.cont.getBoundingClientRect().width
// this.cont得到DOM节点
// this.cont.focus(); 可以对节点进行操作输入框聚焦
// getBoundingClientRect() 的值是 DOMRect = {
x: 112.625
y: 44
width: 32
height: 44
top: 44
right: 144.625
bottom: 88
left: 112.625}
}
render() {
<div ref={r => { this.cont = r }}>……</div>
}
- ref="" 也可以直接赋值一个string
componentDidMount(){
this.refs.cont.getBoundingClientRect().width
const myCount = this.refs.cont
const dom = ReactDOM.findDOMNode(myCount); // 获取到实例对应的DOM节点
}
render() {
<div ref="cont"}>……</div>
}
// this.refs.myCount.method(),但并不建议这种调用方式。
6.React也可以用 a 链接跳转页面,xxxx?a=b&c=d 这种方式
- 需求就是A页面到B页面,在B页通过点击标签来切换内容,但并不用刷新B页同时点击标签的时候,B页的URL参数,要跟随点击标签时对应改变,因为有可能从B页跳到C页,C页回退的B页时,要抓取B页URL最后一次的参数变化。
- [本文参考地址来至饥人谷的若愚 ]zhuanlan.zhihu.com/p/22412047)
// 改变URL的参数值,但不刷新页面
history.pushState({
url: '/#/B?shopId=' + shopId + '&type=2', title: document.title
}, docume.title, "/#/B?shopId=" + shopId + "&type=2")
history.pushState() 带有三个参数:一个状态对象,一个标题(现在被忽略了),以及一个可选的URL地址。
1.状态对象是一个由 pushState()方法创建的与历史纪录相关的JS对象。
2.title — 火狐浏览器现在已经忽略此参数,将来也许可能被使用。考虑到将来有可能的改变,传递一个空字符串是安全的做法。
当然,你可以传递一个短标题给你要转变成的状态。
3.URL — 这个参数提供了新历史纪录的地址。请注意,浏览器在调用pushState()方法后不会去加载这个URL,
但有可能在之后会这样做,比如用户重启浏览器之后。新的URL可以是绝对地址,也可以是相对地址。新URL必须和当前URL在同一个源下。
// 附带解析URL上的参数
parseUrlHash = ()=>{
const data = {
url: null,
params: {}
};
let hash = location.hash;
let paramsString, pair;
if (String.isNotEmpty(hash)) {
hash = hash.replace("#/", "").split("?");
data.url = hash[0];
if (hash.length >= 2) {
paramsString = hash[1].split("&");
for (var i = 0; i < paramsString.length; i++) {
pair = paramsString[i].split("=");
data.params[pair[0]] = pair[1];
}
}
}
return data;
}
7.当我们用less写React样式时,使用calc()计算宽高错误,但以前用scss写样式没出现这毛病
"gulp-sass": "^3.1.0",
height:calc(100% - 0.38rem) // 我以前开发web用JQ的写法可以用
"less": "^2.7.3", "less-loader": "^4.0.5" => 用react做H5的依赖
@tab-header-height: 0.45rem;
@tab-second-height: 0.6rem;
比如: height: calc(~'100% - '@header-height ~'-' @tab-header-height ~'-' @tab-second-height); // 要这样才行
/* Less */
#main{
width:~'calc(300px-30px)';
}
/* 生成后的 CSS */
#main{
width:calc(300px-30px);
}
结构: ~' 值 ' 避免编译
有时候会遇到calc()计算后的结果转为百分比。如
cacl(100% - 580px) 会变为calc(-480%)。这种错误出现在less中使用。
因为less的计算方式与calc有冲突。
解决方案:calc(~“100% - 580px”)
结语
前端react QQ群:
788023830----React/Redux - 地下老英雄前端交流 QQ群:
249620372----FRONT-END-JS前端(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习