Recently, I learned React + Redux, but I felt confused. In order to verify my learning results, I wrote this note specially




The characteristics of story

  • React is not related to Redux. It is a separate technology. To connect the two technologies, use react-Redux.

store

  • Create a store with the redux.createstore method. This store can be used with the React-Redux Provider


let store = createStore(reducers, "Initial value object")
Copy the code


  • Stores are created from reducers, and [Store, Reducers] should be unique
  • Store is the set of all reducer, and state is only the data set in store
  • The Store has the following responsibilities
  • Maintain application state;
  • Provide the getState() method to getState;
  • Provide a dispatch(action) method to update state;
  • Register a listener with subscribe(listener);
  • Unsubscribe the listener via a function returned by subscribe(listener)

reducers

  • Reducers should be unique and can contain multiple multi-level reducers
  • Reducers Contains all managed data (Reducer)


reducers = {
	reducer1,
	reducer2,
	reducer3: {
		reducer4,
		reducer5,
	}
}
Copy the code


  • A Reducer is the smallest unit of a store, and a reducer corresponds to one variable
  • Combine multiple Reducers with redux.combineReducers, and the combined objects are also reducers, which contain all reducers
  • Reducer is a pure function that receives the old state and action and returns the new state


Reducer reducer reducer reducer reducer reducer reducer reducer reducer reducer reducer reducer reducer
// You can use the following method
// State should not be modified
function reducerName(state = "Initial value", action) {
	switch(action.type) {
		case "1":
			return state + 1;
		case "Event 2":
			return state - 1;
		default:
			// No corresponding event returns state
			returnstate; }}Copy the code


action

  • Action is a normal JS object that by convention retains type to indicate the action to be performed. The rest of the action is not specified


action = {
	type: "val1_1__INCREMENT",
	val1,
	val2,
}
Copy the code


store.dispatch

  • Store.dispatch (Action) Dispatches an action to the store
  • Store. Dispatch triggers all reducer events. Therefore, the event names of the reducer must be different

Store. Listen

  • Store. Subscribe to monitor the store
  • Subscribe returns a function, unsubscribe, that executes unsubscribe to stop listening


unsubscribe = store.subscribe(() = >
	// Execute the content after listening
	console.log(store.getState())
)
// Stop listening for state updates
unsubscribe();
Copy the code





The react – characteristics of the story

  • What react-redux does is associate react with redux
  • React-redux distinguishes [container components, presentation components] from other components whose categories are unclear
  • Container components: Describes how to run (data fetch, status update) that is declared in container components before it can be used in presentation components
  • Display components: Describe how to display (skeleton, style), almost like a normal React component, with variables and methods that call redux
  • A presentation component can be a function component or a class component
  • The container component is generated according to the display component, and the superior call is the container component. Generally, the container component is one-to-one with the display component
  • Connect ([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
  • MapStateToProps maps the current Redux store state to the props of the presentation component, (declare variables)
  • The mapDispatchToProps receives the Dispatch () method and returns the callback method expected to be injected into the props of the presentation component, declaring the method
  • mergeProps ???
  • options ???
  • The Store is passed through the React-Redux Provider


render(
	<Provider store={store}>
		<App />
	</Provider>.document.getElementById("root"))Copy the code





demo

import React from "react";

import { Provider, connect } from "react-redux";
import { combineReducers, createStore } from "redux";

function val1_1(state = 0, action) {
	switch (action.type) {
		case "val1_1__INCREMENT":
			return state + 1;
		case "val1_1__DECREMENT":
			return state - 1;
		default:
			returnstate; }}function val1_2(state = 0, action) {
	switch (action.type) {
		case "val1_2__INCREMENT":
			return state + 1;
		case "val1_2__DECREMENT":
			return state - 1;
		default:
			returnstate; }}function val2(state = "Initial value", action) {
	switch (action.type) {
		case "val2__RESET":
			return action.state
		default:
			return state
	}
}

function val3(state = [], action) {
	switch (action.type) {
		case "val3__ADD_TODO":
			return [
				...state,
				{
					text: action.text,
					completed: false}]case "val3__COMPLETE_TODO":
			return state.map((todo, index) = > {
				if (index === action.index) {
					return Object.assign({}, todo, {
						completed: true})}return todo
			})
		default:
			return state
	}
}

let val1 = combineReducers({ val1_1, val1_2 })
let reducers = combineReducers({ val1, val2, val3 })
var store = createStore(reducers)
store.subscribe(() = > {
	console.log(store.getState())
});


// Display the component
// Connect without passing mapDispatchToProps will get dispatch in this.props
class App extends React.Component {
	constructor(props) {
		super(props)
		this.state = {
			thisState: "this.state"};// props.dispatch
	}

	componentDidMount(){}render() {
		const { thisState } = this.state

		// Both methods and variables are passed in from this.props
		const {
			val1,
			val1_1,
			val1_2,
			val2,
			val3,
			val1_1__INCREMENT,
			val1_2__INCREMENT,
			val2__RESET,
			val3__ADD_TODO
		} = this.props

		return (
			<div>
				<button onClick={val1_1__INCREMENT}>Click to trigger val1_1__INCREMENT</button>
				<div>val1.val1_1: {val1.val1_1}</div>
				<div>val1_1: {val1_1}</div>

				<button onClick={val1_2__INCREMENT}>Click to trigger val1_2__INCREMENT</button>
				<div>val1.val1_2: {val1.val1_2}</div>
				<div>val1_2: {val1_2}</div>


				<button onClick={val2__RESET.bind(this,"New value")} >Click to trigger val2__RESET and pass in a new value</button>
				<div>val2: {val2}</div>

				<button onClick={val3__ADD_TODO}>Click to trigger val3__ADD_TODO</button>
				<div>New val3</div>

				{
					val3.map((item, index) => {
						return <div key={index}>{item.text}</div>})}<hr />
				<div>Local data: {thisState}</div>
				{this.props.children ? <div>{this.props.children}</div> : null}
			</div>); }}// Declare variables
function mapStateToProps(state, ownProps) {
	// ownProps: Passes the original props for the presentation component
	// state === store.getState() // true
	return {
		val1: state.val1,
		val1_1: state.val1.val1_1,
		val1_2: state.val1.val1_2,
		val2: state.val2,
		val3: state.val3,
	}
}

// Declare the method
function mapDispatchToProps(dispatch, ownProps) {
	// ownProps: Passes the original props for the presentation component
	return {
		val1_1__INCREMENT: () = > {
			dispatch({
				type: "val1_1__INCREMENT",}}),val1_2__INCREMENT: () = > {
			dispatch({
				type: "val1_2__INCREMENT",}}),val2__RESET: (state) = > {
			dispatch({
				type: "val2__RESET".state: state
			})
		},
		val3__ADD_TODO: () = > {
			dispatch({
				type: "val3__ADD_TODO".text: "text"})}.}}/ / show corresponding components finally received the props material ownProps + mapStateToProps. Return + mapDispatchToProps. Return
// if mapDispatchToProps is empty, props should have dispatch

// Other components
// There is no passing (mapStateToProps, mapDispatchToProps) called other components
// Connect will get dispatch if mapDispatchToProps is not passed
const Bpp = (. rest) = > {
	let dispatch = rest[0].dispatch
	return (
		<div>
			<div onClick={e= >Dispatch ({type: "val1_2__INCREMENT"})}> Modify VAL1_2 from other components</div>
		</div>
	);
};

// Container components
const ConnectApp = connect(mapStateToProps, mapDispatchToProps)(App)
const ConnectBpp = connect()(Bpp)

const ProviderApp = () = > {
	return (
		<Provider store={store}>
			<ConnectApp>Child components<ConnectBpp></ConnectBpp>
			</ConnectApp>
		</Provider>
	);
};

export default ProviderApp

// The demo that the root component calls ProviderApp is not written separately
// import ProviderApp from "./components/ProviderApp";
// render((
// 
      
// ), document.getElementById("react-container"));
Copy the code




end