React + redux general usage instructions

I recently studied react + redux, and I feel rather confused. In order to verify the learning results, I wrote this note specially



Features of redux

  • react has nothing to do with redux, they are two independent technologies. To connect the two, you need to use react-redux (react-redux itself is also an independent technology)

store

  • Use redux.createStore method to create store, this store can be used for react-redux Provider

let store = createStore(reducers, "初始值对象")

  • Store is created according to reducers, [store, reducers] should be unique
  • Store is the collection of all reducers, and state is only the data collection in the store
  • Store has the following responsibilities
  • Maintain the state of the application;
  • Provide getState() method to get state;
  • Provide dispatch(action) method to update state;
  • Register the listener through subscribe(listener);
  • Unregister the listener through the function returned by subscribe(listener)

reducers

  • Reducers should be unique, reducers can contain multiple multi-layer reducers
  • Reducers contain all managed data (reducer)

reducers = {
    
    
	reducer1,
	reducer2,
	reducer3: {
    
    
		reducer4,
		reducer5,
	}
}

  • Reducer is the smallest unit of store, and one reducer corresponds to one variable
  • Combine multiple reducers with redux.combineReducers, the combined object is also a reducer, and the one that contains all reducers is the reducer
  • The reducer is a pure function, receiving the old state and action, and returning the new state

// 只要符合要求并能实现功能, reducer 怎么写都可以
// 常用的写法如下
// state 不应该被修改
function reducerName(state = "初始值", action) {
    
    
	switch(action.type) {
    
    
		case "事件1":
			return state + 1;
		case "事件2":
			return state - 1;
		default:
			// 没对应事件 返回 state
			return state;
	}
}

action

  • action is a normal js object, according to the conventions reserved type to indicate the action to be executed, other parts are not clearly defined

action = {
    
    
	type: "val1_1__INCREMENT",
	val1,
	val2,
}

store.dispatch

  • store.dispatch(action) passes the action to the store
  • store.dispatch will trigger all reducers, so the event name of the reducer should be careful not to have the same name

store.monitor

  • store.subscribe monitor store
  • A function unsubscribe returned by store.subscribe, execute unsubscribe to stop monitoring

unsubscribe = store.subscribe(() =>
	// 监听后执行内容
	console.log(store.getState())
)
// 停止监听 state 更新
unsubscribe();



Features of react-redux

  • The role of react-redux is to connect react and redux
  • react-redux distinguishes [container components, display components], and those that are unclear are called other components
  • Container component: Describe how to run (data acquisition, status update), and only after it is declared in the container component can it be used in the display component
  • Display components: describe how to display (skeleton, style), which is almost a normal react component, with more variables and methods to call redux
  • The display component can be a function component or a class component
  • The container component is generated according to the display component, and the upper level calls the container component. Generally, the container component and the display component have a one-to-one relationship
  • Container component = connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]) (display component)
  • mapStateToProps maps the current Redux store state to the props of the display component, (declare variables)
  • mapDispatchToProps receives the dispatch() method and returns the callback method that is expected to be injected into the props of the display component, and the declaration method
  • mergeProps ???
  • options ???
  • Pass the store through the react-redux Provider

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

-Provider is generally in the root component, but not necessarily in the root component



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:
			return state;
	}
}
function val1_2(state = 0, action) {
    
    
	switch (action.type) {
    
    
		case "val1_2__INCREMENT":
			return state + 1;
		case "val1_2__DECREMENT":
			return state - 1;
		default:
			return state;
	}
}

function val2(state = "初始值", 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())
});


// 展示组件
// connect 没有传入 mapDispatchToProps 将会在 this.props 里得到 dispatch
class App extends React.Component {
    
    
	constructor(props) {
    
    
		super(props)
		this.state = {
    
    
			thisState: "this.state",
		};
		// props.dispatch
	}

	componentDidMount() {
    
     }

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

		// 方法和变量都从 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}>点击触发 val1_1__INCREMENT</button>
				<div>val1.val1_1: {
    
    val1.val1_1}</div>
				<div>val1_1: {
    
    val1_1}</div>

				<button onClick={
    
    val1_2__INCREMENT}>点击触发 val1_2__INCREMENT</button>
				<div>val1.val1_2: {
    
    val1.val1_2}</div>
				<div>val1_2: {
    
    val1_2}</div>


				<button onClick={
    
    val2__RESET.bind(this, "新值")}>点击触发 val2__RESET, 并传入新值</button>
				<div>val2: {
    
    val2}</div>

				<button onClick={
    
    val3__ADD_TODO}>点击触发 val3__ADD_TODO</button>
				<div>新增 val3</div>

				{
    
    
					val3.map((item, index) => {
    
    
						return <div key={
    
    index}>{
    
    item.text}</div>
					})
				}

				<hr />
				<div>本地数据: {
    
    thisState}</div>
				{
    
    this.props.children ? <div>{
    
    this.props.children}</div> : null}
			</div>
		);
	}
}

// 声明变量
function mapStateToProps(state, ownProps) {
    
    
	// ownProps: 传给对应展示组件的原本的 props
	// 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,
	}
}

// 声明方法
function mapDispatchToProps(dispatch, ownProps) {
    
    
	// ownProps: 传给对应展示组件的原本的 props
	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"
			})
		},
	}
}
// 对应展示组件最后收到的 props ≈ ownProps + mapStateToProps.return + mapDispatchToProps.return
// mapDispatchToProps 为空的时候, props 会有 dispatch

// 其它组件
// 没有传入 (mapStateToProps, mapDispatchToProps) 称为其它组件
// connect 没有传入 mapDispatchToProps 将会得到 dispatch
const Bpp = (...rest) => {
    
    
	let dispatch = rest[0].dispatch
	return (
		<div>
			<div onClick={
    
    e => dispatch({
    
     type: "val1_2__INCREMENT" })}>从其它组件修改 val1_2</div>
		</div>
	);
};

// 容器组件
const ConnectApp = connect(mapStateToProps, mapDispatchToProps)(App)
const ConnectBpp = connect()(Bpp)

const ProviderApp = () => {
    
    
	return (
		<Provider store={
    
    store}>
			<ConnectApp>
				子组件
				<ConnectBpp></ConnectBpp>
			</ConnectApp>
		</Provider>
	);
};

export default ProviderApp

// 根组件调用 ProviderApp 的 demo 就不另外写了
// import ProviderApp from "./components/ProviderApp";
// render((
// 	<ProviderApp />
// ), document.getElementById("react-container"));




end

Guess you like

Origin blog.csdn.net/u013970232/article/details/109851343