React日常用法

309 阅读4分钟

setState

官方文档

其他掘金博主参考文档

setState用法参考 最终都是返回一个新的state对象让其合并

核心

setState并非真异步,只是看上去像异步。在源码中通过isBatchingUpdates来判断setState是先存进state队列还是直接更新,如果值为true则执行异步操作,为false则直接更新 场景 在react可以控制的地方,就为true,比如React生命周期事件和合成事件中,都会先存入队列,延迟更新。 在react无法控制的地方,比如原生事件,addEventListener、setTimeout、setInterval等,只能同步更新 合成事件 在react中自定义的方法 合成事件官方文档

// handleOk和handleCancel就为合成事件
<Modal visible={this.state.isModalVisible} onOk={this.handleOk} onCancel={this.handleCancel}>
    <p>是否删除该项</p>
</Modal>

React中事件绑定及优化

官方参考文档

其他掘金博主文档

  • React中的事件绑定存this指向的问题,在render函数中的JSX语法中绑定事件函数,this为undefined,需要讲this指向组件类本身。通过箭头函数或者call、apply、bind改变this指向。
// 箭头函数
<Button type="text" danger onClick={() => this.delHandel(index)}>删除</Button>
// bind改变this指向,通过bind绑定会返回一个改变this指向后的新函数
<Button type="text" danger onClick={this.delHandel.bind(this, index)}>删除</Button>
  • 在 render 方法中使用 Function.prototype.bind 会在每次组件渲染时创建一个新的函数,可能会影响性能

  • 解决通过bind绑定会影响性能的问题(使用bind且要传参)

解决方法一:通过先在constructor中完成this的bind,然后在render函数中直接使用。而参数通过dataset来获取

const A = 65 // ASCII character code

class Alphabet extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      justClicked: null,
      letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
    };
  }

  handleClick(e) {
    this.setState({
      justClicked: e.target.dataset.letter
    });
  }

  render() {
    return (
      <div>
        Just clicked: {this.state.justClicked}
        <ul>
          {this.state.letters.map(letter =>
            <li key={letter} data-letter={letter} onClick={this.handleClick}>
              {letter}
            </li>
          )}
        </ul>
      </div>
    )
  }
}

React中条件渲染和列表渲染

React中父子组件传值

  • 父组件通过属性的方式向子组件传值
// 父组件向CardList组件传递list属性值
<CardList list={this.state.list}/>
// 子组件通过this.props接收
class CardList extends React.Component {
  render() {
    return (
      <Card className="mt-10">
        {
          this.props.list.length > 0?(
            this.props.list.map((item, index)=> {
              return (
                <div className="flex jc-sb ai-c" key={index}>
                  <div>{item}</div>
                  <Button type="text" danger>删除</Button>
                </div>
              )
            })
          ):(
            <p>暂无数据</p>
          )
        }
      </Card>
    )
  }
}
export default CardList
  • 子组件向父组件传值,通过执行父组件传递的回调函数
// 父组件
<CardList list={this.state.list} delHandel={(index) => this.delHandel(index)}/>
// 子组件
import React from 'react'
import { Button, Card } from 'antd'

class CardList extends React.Component {
  render() {
    return (
      <Card className="mt-10">
        {
          this.props.list.length > 0?(
            this.props.list.map((item, index)=> {
              return (
                <div className="flex jc-sb ai-c" key={index}>
                  <div>{item}</div>
                  <Button type="text" danger onClick={() => this.delHandel(index)}>删除</Button>
                </div>
              )
            })
          ):(
            <p>暂无数据</p>
          )
        }
      </Card>
    )
  }
  delHandel(index) {
    console.log(index)
    this.props.delHandel(index)
  }
}
export default CardList

React组件传值PropTypes类型检查

官方参考文档

  • 安装prop-typesnpm i prop-types -S yarn add prop-types
  • 使用
import PropTypes from 'prop-types'
class CardList extends React.Component {}
CardList.propTypes = {
  // props类型,isRequired为必传
  list: PropTypes.array.isRequired
}
CardList.defaultProps = {
  // 默认值
  list: []
}
export default CardList

React中使用refs获取DOM

  • 可以操作 dom
  • react 是不建议使用 ref 的,因为 setState 是一个异步函数不会被立即执行,dom 的数据更新并不及时,如果你希望页面更新之后再去更新 dom,你要把获取 dom 的语法方法在 setState 第二个参数的函数里面(回调函数)
this.setState(
  (prevState) => {},
  () => {
     console.log("获取更新之后的dom")
  }
);

React动画

  • 使用 react-transition-group
  • 安装 npm install react-transition-groupyarn add react-transition-group
  • 参考文档

React样式模块 styled-components

  • 安装 npm install --save styled-componentsyarn add styled-components
  • 参考文档

跨域,使用http-proxy-middleware 中间件

  • 安装 npm install http-proxy-middleware --saveyarn add http-proxy-middleware
  • 在 src 下创建 setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
  app.use(
    createProxyMiddleware('/api', {
      target: 'http://localhost:8000',
    })
  );
};

参考文章

React.Component 和 React.PureComponent的区别

  • PureComponent优点:不需要开发者自己实现 shouldComponentUpdate,就可以自动判断来提升性能

  • PureComponent缺点:可能会因深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate结果返回false,界面得不到更新。

  • 如果你使用 immutable 进行数据管理,可以将组件的继承 Component 都改成 PureComponent 可以很好的提升性能.如果没有使用 immutable,建议还是使用 component,因为这个有时候会遇到小坑,如果没有使用 immutable 进行数据管理,你也可以自己写 shouldComponentUpdate 进行性能的优化

  • PureComponent 内置了类似组件 shouldComponentUpdate 钩子,对于与自己组件无关的数据改变,不会重新渲染,大大提高了性能.

JSX中return后面加括号表示什么意思

  • JS中圆括号表示执行符号,在render中是给babel-jsx解析用的
  • return中的圆括号是为了代码换行,不用括号的话只能写一行