Water can put the stone through, ten thousand efforts to natural – zZ Sen

No more talking, get straight to the dry stuff!

Property-based pass props

The parent component invokes its child components and passes properties to its children. This is one-way data transmission. That is, the parent component can only pass properties to its child components, and vice versa.

The child component passes information to the parent

Callback function:

The parent component passes the method that can manipulate its state to the child component through properties, and then the child component takes the method and modifies the corresponding information through the method. The bottom layer is still based on attribute passing

JSONP and JSBridge operate similarly to callback functions

Publish and subscribe:Based on the$onand$emitRealization of information communication

Implement a publish subscription manually:

Class EventEmit{// Event pool {event name: [Subscribe method...] } pond = {};$on(eventName,func){
        if(! This.pond.hasownproperty (eventName) {// each eventName corresponds to a series of methods this.pond.eventname = []; } this.pond[eventName].some(item=>item===func)return;
        this.pond[eventName].push(func)
    }
    $emit(eventName,... rargs){letfunArr = this.pond[eventName]||[]; funcArr.forEach(item=>{ item.bind(null,... args) }) }export default new EventEmit();
}
Copy the code
import React from "react";
import EM from "./EventEmit";
class Main tetends React.component{
    state = {
        supNum:0,
        oppNum:0
    }
    handle=(type) = > {let {subNum,oppNum} = this.state;
        if(type= = ="sup"){ this.setState({ subNum:subNum++; })}else{ this.setState({ this.setState({ oppNum:oppNum++; }}})})render() {let {oppNum,oppNum} = this.state;
        return <main className="mainBox"> < p > the number of support {supNum} < / p > < p > number against {oppNum} < / p > < / main >}componentDidMount(){
        EM.$on("mainHandle",handle)
    }
}

class Footer extends React.component{
    render() {return <footer className="footerBox">
        <button onClick = {ev=>{
            EM.$emit("mainHandle"."SUP");
            EM.$emit("totalHandle"</button> <button onClick = {ev=>{EM.$emit("mainHandle"."OPP")
            EM.$emit("totalHandle"</button> </footer>}}export default class Vote extends React.component{
    state = {total:0}
    return {
        <div className="voteBox">
           <header className="headerBox"> < h3 > {this. Props. The title} < / h3 > < span > turnout: {this. State. Total} < / span > < header > < Main > < / Main > < Footer > < Footer > < div >}componentDidMount(){
        EM.$on("totalHandle",()=>{
            this.setState({
                total:this.state.tota+1
            })
        })
    }
}
Copy the code

Execution context for information passing:

By placing attributes and methods needed by descendant components in the context of the ancestor element, descendant components can register and use them directly. [For components that have a common ancestor]

Functional component HOOKS

  • 1. Create context object ThemeContext:React.createContext();
// Create a CONTEXT object (REACT CONTEXT API [latest]) import REACT from'react';
const ThemeContext = React.createContext();
export default ThemeContext;
Copy the code
  • 2. Create a context on the ancestorThemeContext.Provider value={... }
return{< themecontext.provider value=({// Context information to provide... state })> </ThemeContext.Provider> }Copy the code

Tip: The context we need to use is usually set to the state of the ancestor element, so that we can change the state later and trigger the getInitialState hook function to execute and re-render, which will reset the context information and re-render the descendant components and get the latest information.

  • 3. Use context information in descendant componentscontext=React.useContext(ThemeContext)
    Const {handle} = useContext(ThemeContext); const {handle} = useContext(ThemeContext);Copy the code

Class components

  • REACT is available in version 15Warning error in StrictModel mode
    • Specifies the type of property that can be used by descendant componentsstatic childContextTypes = {... }
    • Provide data interfaces to descendant componentsgetChildContext(){return{... }}[Also a lifecycle function]
    • Descendant registrationstatic contextTypes = {... }Declare that the state type must be the same as that provided by the ancestor component.
import React from 'react';
import PropTypes from 'prop-types'; Class Main extends react.ponent {// The context information is mounted to the this.context of the instance. Static contextTypes = {supNum: proptypes. number, oppNum: proptypes. number}; /*constructor(props, context) { super(props, context); } * /render() {
		return <main className="mainBox"> <p> support number: {this.context.supNum}</p> <p> Oppose number: {this.context.oppNum}</p> </main>; } } class Footer extends React.Component { static contextTypes = { handle: PropTypes.func };render() {
		return <footer className="footerBox">
			<button onClick={ev => {
				this.context.handle('SUP'); }}> support </button> <button onClick={ev => {this.context.handle('OPP'); </button> </footer>; }}export default class Vote extends React.Component {
	static childContextTypes = {
		supNum: PropTypes.number,
		oppNum: PropTypes.number,
		handle: PropTypes.func
	};
	getChildContext() {//=> This hook function is first executed after getIntialState, and is re-executed whenever the state in the ancestor component changes and is re-renderedreturn {
			supNum: this.state.supNum,
			oppNum: this.state.oppNum,
			handle: this.handle
		}
	}
	state = {
		supNum: 0,
		oppNum: 0
	};
	handle = type= > {let { supNum, oppNum } = this.state;
		type= = ='SUP' ? this.setState({ supNum: supNum + 1 }) : this.setState({ oppNum: oppNum + 1 });
	};
	render() {
		return <div className="voteBox">
			<header className="headerBox"> < h3 > {this. Props. The title} < / h3 > < span > N: {this.state.supNum + this.state.oppNum}</span> </header> <Main></Main> <Footer></Footer> </div>; }}Copy the code
  • React new version specification
    • Based on theThemeContext.ProviderValue in registers context information
      import React from 'react';
      import VoteMain from './VoteMain';
      import VoteFooter from './VoteFooter';
      import ThemeContext from './ThemeContext';
      
      export default class Vote extends React.Component {
      state = {
      	supNum: 0,
      	oppNum: 0
      };
      
      render() {
      	let{ supNum, oppNum } = this.state; /* Register context information based on the value in themecontext.provider */return <ThemeContext.Provider
      		value={{
      			supNum,
      			oppNum,
      			handle: this.handle
      		}}>
      		<div className="voteBox">
      			<header className="voteHeader"<span> </span> </header> </VoteMain> </VoteMain> </VoteFooter> </VoteFooter>  </div> </ThemeContext.Provider>; } handle = (lx = 0) => {// Supportif (lx === 0) {
      		this.setState({ supNum: this.state.supNum + 1 });
      		return; } // Object this.setState({oppNum: this.state.oppnum + 1}); }};Copy the code
    • Descendant components use context information
      • Use context information based on the Consumer component
      import React from 'react';
      import ThemeContext from './ThemeContext';
      export default class voteMain extends React.Component {
      render() {
      	return <ThemeContext.Consumer>
      		{context => {
      			let { supNum, oppNum } = context;
      			return <main className="voteMain"> < p > support number: {supNum} < / p > < p > antilog: {oppNum} < / p > < p > support: {this. Thewire (supNum oppNum)} < / p > < / main >; }} </ThemeContext.Consumer>; } ratio = (supNum, oppNum) => {let total = supNum + oppNum;
      	if (total === 0) return The '-';
      	return (supNum / total * 100).toFixed(2) + The '%'; }}Copy the code
      • throughthis.context
      import React from 'react';
      import ThemeContext from './ThemeContext';
      
      export default class voteFooter extends React.Component {
      static contextType = ThemeContext;
      
      render() {
      	return <footer className="voteFooter">
      		<button onClick={_ => {
      			this.context.handle(0);
      		}}>支持</button>
      
      		<button onClick={_ => {
      			this.context.handle(1);
      		}}>反对</button>
      	</footer>;
          }
       };
      Copy the code

conclusion

The most commonly used method in projects is to pass PROPS based on properties, and to pass context based on execution. The most commonly used method is Redux based on common state management because it is a bit cumbersome to place context in ancestor components. Follow-up continuous summary update!