Redux, React-redux introduction

redux

A brief introduction to Redux, which will be used in more detail below.

It works in the same way as VUEX, applying global state data management and combining react immutable values with pure functions

Unidirectional data flow description

dispatch(action)

reducer -> newState

Subscribe trigger notification

react-redux

Two concepts

  • UI component: can’t use any REdux API (dispatch…) Is only responsible for page rendering, interaction, etc.
  • Container component: Responsible for communicating with Redux and returning the results to the UI component

Two core

The connect function

How do I create a container component? React-redux connect high-order function

Connect (mapStateToProps, mapDispatchToProps)(UI component)

  • MapStateToProps: Mapping status, the return value is an object
    • The mapStateToProps function returns an object;
    • The key in the returned object is the key passed to the UI component props, and the value is the value passed to the UI component props
    • MapStateToProps is used to pass state
  • MapDispatchToProps: method for mapping the state of an operation, and the return value is an object
    • The mapDispatchToProps function returns an object;
    • The key in the object is the key passed to the UI component props, and the value is the value passed to the UI component props
    • MapDispatchToProps a method for passing operational status

The Provider component

Instead of using provider, you need to pass store to container components, if there are too many components…… .

<Count store={store}></Count>
<Count1 store={store}></Count1>
<Count2 store={store}></Count2>.Copy the code

This is not the case with the Provider component, and giving a package enables store to be used in all components.

<Provider store={store}>
    <App/>
</Provider>
Copy the code

React-redux selects to add cases

Count.jsx

// The click event only gets the selected value.
// React-redux has not been introduced yet
export default class Count extends Component {
	/ / add
	increment = () = >{
		const {value} = this.selectNumber
	}
	// Add the odd number
	incrementIfOdd = () = >{
		const {value} = this.selectNumber
	}
	/ / asynchronous
	incrementAsync = () = >{
		const {value} = this.selectNumber
	}

	render() {
		// console.log(' the UI component is receiving props ',this.props);
		return (
			<div>
				<h1>The current sum is:</h1>
				<select ref={c= > this.selectNumber = c}>
					<option value="1">1</option>
					<option value="2">2</option>
					<option value="3">3</option>
				</select>&nbsp;
				<button onClick={this.increment}>+</button>&nbsp;
				<button onClick={this.incrementIfOdd}>The sum is now odd plus</button>&nbsp;
				<button onClick={this.incrementAsync}>Asynchronous add</button>&nbsp;
			</div>)}}Copy the code

App.jsx

</div> <Count></Count> <div>

Index.js entry file

ReactDOM.render(
	<App/>.document.getElementById('root'))Copy the code

So far, it’s just some simple code. I haven’t used React-Redux yet.

// create constant.js to place type values that are easy to write incorrectly
export const INCREMENT = 'INCREMENT'
Copy the code

store.js

/* This file is specifically used to expose a store object, the entire application has only one store object */

// createStore is introduced to create the core store object in Redux
// applyMiddleware is a Redux application
import {createStore,applyMiddleware} from 'redux'
// Import the reducer as the Count component service
import countReducer from './count_reducer'
// Redux-thunk is introduced to support asynchronous action
// If redux-thunk is not used here, the following asynchronous action will not take effect
import thunk from 'redux-thunk'
//暴露store
export default createStore(countReducer,applyMiddleware(thunk))
Copy the code

count_reducer.js

  1. This file is used to create a Reducer for the Count component service, which is essentially a function
  2. The reducer function receives two parameters, preState and Action.
  3. Initialize state. Why do I need to initialize state? When you pass undefined or the initial state is undefined, it throws an exception.
import * as types from './constant'
// Initialize state or manually check whether the first parameter is undefined in the reducer function.
const initState = 0 
export default function countReducer(preState = initState,action){
	// console.log(preState);
	// Get type and data from the action object
   	// This data and type correspond to the action in count_action.js below
	const {type,data} = action
	// How to process data according to type
	switch (type) {
		case types.INCREMENT:
			return preState + data
		default:
			return preState
	}
}
Copy the code

count_action.js

  1. You must use a string type field within the action to indicate the action to be performed
/* This file specifically generates the action object */ for the Count component
import * as types from './constant'

// Synchronous action is a generic Object whose action value is of type Object
// Note: The type and data here correspond to the type and data obtained from the action parameter in the Reducer
export const createIncrementAction = data= > ({type:types.INCREMENT,data})

// An asynchronous action is an action whose value is a function. In an asynchronous action, a synchronous action is usually called. In this case, an AXIOS request is sent to invoke the synchronous action.
// Redux-thunk is used to support asynchronous action.
export const createIncrementAsyncAction = (data,time) = > {
	return (dispatch) = >{
        // Send the request..... Access to the data
		setTimeout(() = >{
			dispatch(createIncrementAction(data))
		},time)
	}
}
Copy the code

Finally, you need to use the connect function on the Count component.

class Count extends Component {
	/ / add
	increment = () = >{
		const {value} = this.selectNumber
        this.props.jian(value*1)}/ / asynchronous
	incrementAsync = () = >{
		const {value} = this.selectNumber
		this.props.jiaAsync(value*1.500)}render() {
		// console.log(' the UI component is receiving props ',this.props);
		return (
			<div>
				<h1>The current sum is: {this.props. Count}</h1>
				<select ref={c= > this.selectNumber = c}>
					<option value="1">1</option>
					<option value="2">2</option>
					<option value="3">3</option>
				</select>&nbsp;
				<button onClick={this.increment}>+</button>&nbsp;
				<button onClick={this.incrementIfOdd}>The sum is now odd plus</button>&nbsp;
				<button onClick={this.incrementAsync}>Asynchronous add</button>&nbsp;
			</div>)}}// Arrow functions return objects with ()
const mapStateToProps = state= > ({count:state})

const mapDispatchToProps = dispatch= >({jia:number= > dispatch(createIncrementAction(number)),
		jiaAsync:(number,time) = > dispatch(createIncrementAsyncAction(number,time)),
	}
)

// Create and expose a Count container component with connect()()
export default connect(mapDispatchToProps,mapDispatchToProps)(Count)
Copy the code

Don’t forget that you need to wrap your App with the Provider component and pass it into the Store

import store from './redux/store'
import {Provider} from 'react-redux'

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

This completes the case for the addition.

Please point out any mistakes or inadequacies. Thanks for watching.