react传递函数_React开发必须知道的34个技巧

dd675eee7398f741f2de5fe04a8480e3.png

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

1、组件通讯

1.1道具

子组件

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 (      
这是通过 props 传入的值{this.props.name}
点击改变父元素值
); }}

父组件

this.eightteenChildOneToFather(mode)}> // 或者

传传值时:
传统写法

const {dataOne,dataTwo,dataThree} = this.state

升级写法

1.2道具升级版

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

调用父组件方法改变该值

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

1.3提供者,消费者和上下文

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) =>          );    return 
{children}
; }}MessageList.childContextTypes = { color: React.PropTypes.string text: React.PropTypes.string};//中间组件class Message extends React.Component { render() { return (
Delete
); }}//孙组件(接收组件)class MessageItem extends React.Component { render() { return (
{this.context.text}
); }}MessageItem.contextTypes = { text: React.PropTypes.string //React.PropTypes在 15.5 版本被废弃,看项目实际的 React 版本};class Button extends React.Component { render() { return ( {this.props.children} ); }}Button.contextTypes = { color: React.PropTypes.string};

2.16.x之后的上下文使用了提供商和客户模式,在某些提供商的初始值,在子孙级的消费者中获取该值,并且能够传递函数,修改了上下文声明了一个上下文的定义,上下文.js

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

父组件导入

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

父组件定义的值:{name}

子组件

// 导入Consumerimport { Consumer } from "../../utils/context"function Son(props) {  return (    //Consumer容器,可以拿到上文传递下来的name属性,并可以展示对应的值          {name => (        
// 在 Consumer 中可以直接通过 name 获取父组件的值

子组件。获取父组件的值:{name}

)} );}export default Son;

1.4 EventEmitter

EventEmiter传送门 使用事件插件定义一个类别的事件机制

1.5路由传参

1.参数

xxxthis.props.history.push({pathname:"/path/" + name});读取参数用:this.props.match.params.name

2.查询

this.props.history.push({pathname:"/query",query: { name : 'sunny' }});读取参数用: this.props.location.query.name

3.状态

 this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }});读取参数用: this.props.location.query.state

4.搜索

xxxthis.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(组件实例)当做参数传到父组件,父组件就可以操作子组件的状态和方法

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 (      
{this.state.name}
点击改变组件EightteenChildFour的name 值
); }}

seven.jsx

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

1.7参考

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

.jsx

// 常用的组件定义方法export default class EightteenChildFive extends React.Component {  state={      name:'这是组件EightteenChildFive的name 值'  }  click = () => {    this.setState({name:'这是组件click 方法改变EightteenChildFive改变的name 值'})  };  render() {    return (      
{this.state.name}
点击改变组件EightteenChildFive的name 值
); }}

seven.jsx

// 钩子获取实例componentDidMount(){    console.log('eightteenChildFive的Ref值为')      // 获取的 ref 里面包括整个组件实例,同样可以拿到子组件的实例    console.log(this.refs["eightteenChildFiveRef"])  }// 组件定义 ref 属性

1.8 Redux

redux是一个独立的事件通讯插件,这里就不做过多的叙述

1.9 MobX

MobX也是一个独立的事件通讯插件,这里就不做过多的叙述

1.10通量

flux也是一个独立的事件通讯插件,这里就不做过多的叙述

1.11挂钩

1.hooks是利用userReducer和context实现通讯,下面模拟实现一个简单的redux
2.核心文件分为action,reducer,键入
action.js

import * as Types from './types';export const onChangeCount = count => ({    type: Types.EXAMPLE_TEST,    count: count + 1})

reducer.js

import * as Types from "./types";export const defaultState = {  count: 0};export default (state, action) => {  switch (action.type) {    case Types.EXAMPLE_TEST:      return {        ...state,        count: action.count      };    default: {      return state;    }  }};

types.js

export const EXAMPLE_TEST = 'EXAMPLE_TEST';

18.jsx

export const ExampleContext = React.createContext(null);//创建createContext上下文// 定义组件function ReducerCom() {  const [exampleState, exampleDispatch] = useReducer(example, defaultState);  return (      );}

EightteenChildThree.jsx //组件

import React, {  useEffect, useContext } from 'react';import {Button} from 'antd'import {onChangeCount} from '../../pages/TwoTen/store/action';import { ExampleContext } from '../../pages/TwoTen/eighteen';const Example = () => {    const exampleContext = useContext(ExampleContext);    useEffect(() => { // 监听变化        console.log('变化执行啦')    }, [exampleContext.exampleState.count]);    return (        

值为{exampleContext.exampleState.count}

exampleContext.dispatch(onChangeCount(exampleContext.exampleState.count))}>点击加 1
)}export default Example;

3.hooks实际上就是对常设React的API进行了封装,暴露比较方便使用的钩子;

4.钩子有:

cda3f2dabe35ab9ff493dfe22aa85a2e.png

5,使用即时方法

function FancyInput(props, ref) {  const inputRef = useRef();  useImperativeMethods(ref, () => ({    focus: () => {      inputRef.current.focus();    }  }));  return ;}FancyInput = forwardRef(FancyInput);

1.12插槽

slot就是将父组件的标签传给子组件,类似vue的v-slot
场景:一些组件只是共享部分dom逻辑,里面有部分逻辑是独立的

// 父组件文件import SlotChild from 'SlotChild'这是父组件的 slot
}>// 子组件子组件直接获取 this.props.slot 就可获取到内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值