React 开发必须知道的 34 个技巧【近1W字】

本文详述了React开发中的34个关键技巧,包括组件通讯的各种方式(如props、Context、EventEmitter等)、状态管理和状态变化监听、组件定义与优化(如PureComponent、memo)、React-Router的使用以及样式引入等,旨在帮助React初学者和有经验的开发者提升技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React 开发必须知道的 34 个技巧【近1W字】

前言

React 是前端三大框架之一,在开发中也是一项技能;
本文从实际开发中总结了 React 开发的一些技巧技巧,适合 React 初学或者有一定项目经验的同学

1 组件通讯

1.1 props

子组件

import React from "react";
import PropTypes from "prop-types";
import { Button } from "antd";

export default class EightteenChildOne extends React.Component {
  static propTypes = { //propTypes校验传入类型,详情在技巧11
    name: PropTypes.string
  };

  click = () => {
    // 通过触发方法子传父
    this.props.eightteenChildOneToFather("这是 props 改变父元素的值");
  };

  render() {
    return (
      <div>
        <div>这是通过 props 传入的值{this.props.name}</div>
        <Button type="primary" onClick={this.click}>
          点击改变父元素值
        </Button>
      </div>
    );
  }
}

复制代码

父组件

<EightteenChildOne name={'props 传入的 name 值'} eightteenChildOneToFather={(mode)=>this.eightteenChildOneToFather(mode)}></EightteenChildOne> 

// 或者
<EightteenChildOne name={'props 传入的 name 值'} eightteenChildOneToFather={this.eightteenChildOneToFather.bind(this)}></EightteenChildOne> 
复制代码

props 传多个值时:
传统写法

const {dataOne,dataTwo,dataThree} = this.state
<Com dataOne={dataOne} dataTwo={dataTwo} dataThree={dataThree}>
复制代码

升级写法

<Com {...{dataOne,dataTwo,dataThree}}>
复制代码

1.2 props 升级版

原理:子组件里面利用 props 获取父组件方法直接调用,从而改变父组件的值
注意: 此方法和 props 大同小异,都是 props 的应用,所以在源码中没有举例

调用父组件方法改变该值

// 父组件
state = {
  count: {}
}
changeParentState = obj => {
    this.setState(obj);
}
// 子组件
onClick = () => {
    this.props.changeParentState({ count: 2 });
}
复制代码

1.3 Provider,Consumer和Context

1.Context在 16.x 之前是定义一个全局的对象,类似 vue 的 eventBus,如果组件要使用到该值直接通过this.context获取

//根组件
class MessageList extends React.Component {
  getChildContext() {
    return {color: "purple",text: "item text"};
  }

  render() {
    const {messages} = this.props || {}
    const children = messages && messages.map((message) =>
      <Message text={message.text} />
    );
    return <div>{children}</div>;
  }
}

MessageList.childContextTypes = {
  color: React.PropTypes.string
  text: React.PropTypes.string
};

//中间组件
class Message extends React.Component {
  render() {
    return (
      <div>
        <MessageItem />
        <Button>Delete</Button>
      </div>
    );
  }
}

//孙组件(接收组件)
class MessageItem extends React.Component {
  render() {
    return (
      <div>
        {this.context.text}
      </div>
    );
  }
}

MessageItem.contextTypes = {
  text: React.PropTypes.string //React.PropTypes在 15.5 版本被废弃,看项目实际的 React 版本
};

class Button extends React.Component {
  render() {
    return (
      <button style={
  
  {background: this.context.color}}>
        {this.props.children}
      </button>
    );
  }
}

Button.contextTypes = {
  color: React.PropTypes.string
};
复制代码

2.16.x 之后的Context使用了Provider和Customer模式,在顶层的Provider中传入value,在子孙级的Consumer中获取该值,并且能够传递函数,用来修改context 声明一个全局的 context 定义,context.js

import React from 'react'
let { Consumer, Provider } = React.createContext();//创建 context 并暴露Consumer和Provider模式
export {
    Consumer,
    Provider
}
复制代码

父组件导入

// 导入 Provider
import {Provider} from "../../utils/context"

<Provider value={name}>
  <div style={
  
  {border:'1px solid red',width:'30%',margin:'50px auto',textAlign:'center'}}>
    <p>父组件定义的值:{name}</p>
    <EightteenChildTwo></EightteenChildTwo>
  </div>
</Provider>
复制代码

子组件

// 导入Consumer
import { Consumer } from "../../utils/context"
function Son(props) {
  return (
    //Consumer容器,可以拿到上文传递下来的name属性,并可以展示对应的值
    <Consumer>
      {name => (
        <div
          style={
  
  {
            border: "1px solid blue",
            width: "60%",
            margin: "20px auto",
            textAlign: "center"
          }}
        >
        // 在 Consumer 中可以直接通过 name 获取父组件的值
          <p>子组件。获取父组件的值:{name}</p>
        </div>
      )}
    </Consumer>
  );
}
export default Son;
复制代码

1.4 EventEmitter

EventEmiter 传送门 使用 events 插件定义一个全局的事件机制

1.5 路由传参

1.params

<Route path='/path/:name' component={Path}/>
<link to="/path/2">xxx</Link>
this.props.history.push({pathname:"/path/" + name});
读取参数用:this.props.match.params.name
复制代码

2.query

<Route path='/query' component={Query}/>
<Link to={
  
  { pathname : '/query' , query : { name : 'sunny' }}}>
this.props.history.push({pathname:"/query",query: { name : 'sunny' }});
读取参数用: this.props.location.query.name
复制代码

3.state

<Route path='/sort ' component={Sort}/>
<Link to={
  
  { pathname : '/sort ' , state : { name : 'sunny' }}}> 
this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }});
读取参数用: this.props.location.query.state 
复制代码

4.search

<Route path='/web/search ' component={Search}/>
<link to="web/search?id=12121212">xxx</Link>
this.props.history.push({pathname:`/web/search?id ${row.id}`});
读取参数用: this.props.location.search
复制代码

这个在 react-router-dom: v4.2.2有 bug,传参跳转页面会空白,刷新才会加载出来

5.优缺点

1.params在HashRouter和BrowserRouter路由中刷新页面参数都不会丢失
2.state在BrowserRouter中刷新页面参数不会丢失,在HashRouter路由中刷新页面会丢失
3.query:在HashRouter和BrowserRouter路由中刷新页面参数都会丢失
4.query和 state 可以传对象
复制代码

1.6 onRef

原理:onRef 通讯原理就是通过 props 的事件机制将组件的 this(组件实例)当做参数传到父组件,父组件就可以操作子组件的 state 和方法

EightteenChildFour.jsx

export default class EightteenChildFour extends React.Component {
  state={
      name:'这是组件EightteenChildFour的name 值'
  }

  componentDidMount(){
    this.props.onRef(this)
    console.log(this) // ->将EightteenChildFour传递给父组件this.props.onRef()方法
  }

  click = () => {
    this.setState({name:'这是组件click 方法改变EightteenChildFour改变的name 值'})
  };

  render() {
    return (
      <div>
        <div>{this.state.name}</div>
        <Button type="primary" onClick={this.click}>
          点击改变组件EightteenChildFour的name 值
        </Button>
      </div>
    );
  }
}
复制代码

eighteen.jsx

<EightteenChildFour onRef={this.eightteenChildFourRef}></EightteenChildFour>

eightteenChildFourRef = (ref)=>{
  console.log('eightteenChildFour的Ref值为')
  // 获取的 ref 里面包括整个组件实例
  console.log(ref)
  // 调用子组件方法
  ref.click()
}
复制代码

1.7 ref

原理:就是通过 React 的 ref 属性获取到整个子组件实例,再进行操作

EightteenChildFive.jsx

// 常用的组件定义方法
export default class EightteenChildFive extends React.Component {
  state={
      name:'这是组件EightteenChildFive的name 值'
  }

  click = () => {
    this.setState({name:'这是组件click 方法改变EightteenChildFive改变的name 值'})
  };

  render() {
    return (
      <div>
        <div>{this.state.name}</div>
        <Button type="primary" onClick={this.click}>
          点击改变组件EightteenChildFive的name 值
        </Button>
      </div>
    );
  }
}
复制代码

eighte

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值