react 实际开发,持续回顾

449 阅读4分钟

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前端

(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习