Popover class component design and implementation

Design ideas

The popover class component requires that the popover content be declared at A and displayed at B. React’s equivalent popover content appears to be rendered into a component, but actually changes the DOM structure of a different part of the page. This doesn’t make sense. However, the task can still be accomplished by creating component instances using the specific API provided by the framework and specifying a mount target.

The common usage is as follows: Dialog is declared by the current component, but is displayed in a separate div within the body

import React, {Component} from "react";
import Dialog from ".. /conponents/Dialog";
export default class DialogPage extends Component {
	constructor(props) {
		super(props);
		this.state = {
			showDialog: false
	 	};
}
render() {
	const {showDialog} = this.state;
	return (
		<div>
			<h3>DialogPage</h3> 
			<button  onClick={()= >this.setState({showDialog: ! showDialog})}> toggle</button>
		 	{showDialog && <Dialog />}
		</div>
 );
 }}
Copy the code

Implementation: Portal

After React V16, Portal provides the content transfer function.

Example: Dialog component (dialog.js)

import React, { Component } from "react";
import { createPortal } from "react-dom";

export default class Dialog extends Component {
	constructor(props) {
		super(props);
		const doc = window.document;
		this.node = doc.createElement("div");
		doc.body.appendChild(this.node);   
 	}
 	// External divs are cleared when unmounted
	componentWillUnmount() {   
		window.document.body.removeChild(this.node);
	}
	render() {
		const { hideDialog } = this.props;
		return createPortal(
		 <div className="dialog">
 			{this.props.children}
 			{typeof hideDialog === "function" && (
			<button onClick={hideDialog}>Turn off the pop-ups</button>
 		)}
		</div>.this.node,
 );
 }}
Copy the code

To summarize: All Dialog does is draw the object in another corner of the DOM tree by calling createPortal.

Reducer

Reducer is a pure function that receives the old state and action and returns the new state.

;(previousState, action) = > newState
Copy the code

This function is called reducer because it is the same as the reducer (Reducer,? The callback functions in initialValue are of the same type. It is important to keep reducer pure. Never do these things in a Reducer:

  • Modify the passed parameter;
  • Perform operations that have side effects, such as API requests and route jumps;
  • Call an impure function, such asDate.now()Math.random()

What is the reduce

const array1 = [1.2.3.4];
const reducer = (accumulator, currentValue) = > accumulator
+ currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15
Copy the code

Redux started

Redux is a state container for JavaScript applications. It ensures consistent program behavior and is easy to test.

Install the story

yarn add redux
Copy the code

Redux is difficult to get started with because there are so many concepts to learn from the beginning, using an accumulator as an example:

  1. You need a store to store data
  2. The Reducer in the store initializes state and defines state modification rules
  3. Submit changes to the data by dispatching an action
  4. Actions are submitted to the Reducer function and new states are returned based on the action type that was passed in

Take a chestnut

Create store, SRC /store/index.js

import {createStore} from "redux";
export const counterReducer = (state = 0, {type, payload = 1}) = > {
	switch (type) {
		case "ADD":
			return state + payload;
		// If state is an object
		// return {... state, ... newState};
		case "MINUS":
			return state - payload;
		default:
			returnstate; }};const store = createStore(countReducer);
export default store;
Copy the code

2. Create ReduxPage

import React, {Component} from "react";
import store from ".. /store/";
export default class ReduxPage extends Component {
	componentDidMount() {
		this.unsubscribe = store.subscribe(() = > {
		this.forceUpdate();
 		});
 	}
	componentWillUnmount() {
		this.unsubscribe();
 	}
	add = () = > {
		store.dispatch({type: "ADD"});
 	};
	minus = () = > {
		store.dispatch({type: "MINUS"});
 	};
	render() {
		console.log("store", store); //sy-log
	return (
		<div> 
		<h3>ReduxPage</h3> 
		<p>{store.getState()}</p> 
		<button onClick={this.add}>add</button> 
		<button onClick{this.minus} >minus</button>
		</div>
 );
 }}
Copy the code

Note: If the button cannot be updated, check to see if the subscribe status changes.

You can also subscribe to state changes in SRC /index.js render

import store from './store/'
const render = () = >{
	ReactDom.render( <App/>.document.querySelector('#root')
 )
}
render()
store.subscribe(render)
Copy the code