simple preparation
- quickly build react projects through create-react-app
- install dependent npm install redux react-redux redux-thunk-- save (redux-thunk is middleware for handling asynchronous data streams)
- change, create a new project directory
- effect diagram
Demo start
write redux related content
action
export const Increment = 'increment'
export const Decrement = 'decrement'
/*Action creator action constructor*/
export const increment = (counterIndex) => {
type:Increment,
counterIndex
}
export const decrement = (counterIndex) => ({
type: Decrement,
counterIndex
})
Action is essentially a JavaScript normal object. A type field of string type must be used in action to represent the action to be performed, but you need to write as many action as you need to write action, so you need action creator. This action constructor returns a js object. Of course, you need to return a function when dealing with asynchronous data. In this case, middleware is needed to rewrite dispatch.
reducer
import { Increment, Decrement } from '../Action'
export default (state,action) => {
const {counterIndex} = action
switch (action.type) {
case Increment:
return {...state, [counterIndex]:state[counterIndex]+1}
case Decrement:
return {...state, [counterIndex]:state[counterIndex]-1}
default:
return state
}
}
the specific definition of reducer can be found in the redux README. Since demotion is too simple, let's split and merge reducer. Here we mainly introduce the workflow of redux in react. Note here that reducer is a pure function and cannot change state. The new state returned here can use Object.assign and the object extender of es6.
store
import {applyMiddleware, createStore} from 'redux'
import thunk from 'redux-thunk'
import reducer from '../Reducer'
const initValue={
'First':1,
'Second':5,
'Third':6
}
const store=createStore(reducer,initValue)
export default store
createStorestore can accept an initial state, where you can set the initialization props of the server-side isomorphic application. At this point, the correlation of redux is over, and the ui component is written below.
write UI components
if you don't need react-redux to automatically generate container components, the component division will have to distinguish between container components and presentation. The presentation component I understand is that it does not have its own state and only accepts props to determine how the UI should be displayed. All the logic is carried out in the container component. Because of react-redux, we do not need to write container components
Counter
import React, { Component } from 'react';
import {increment, decrement} from '../Redux/Action'
import {connect} from 'react-redux'
import '../style/App.css';
const buttonMargin= {
margin: "20px"
}
function Counter({index, Increment, Decrement, value}){
return (
<div>
<button style={buttonMargin} onClick={Increment}>+</button>
<button style={buttonMargin} onClick={Decrement}>-</button>
<span>{index} count :{value}</span>
</div>
)
}
function mapStateToProps(state,ownProps){
return{
value:state[ownProps.index]
}
}
function mapDispatchToProps(dispatch, ownProps){
return{
Increment:() => {
dispatch(increment(ownProps.index))
},
Decrement:() => {
dispatch(decrement(ownProps.index))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
- react-redux provides methods connect () and components. Here we talk about connect (), citing the summary of Ruan Yifeng:
The connect method accepts two parameters: mapStateToProps and mapDispatchToProps. They define the business logic of the UI component. The former is responsible for the input logic, that is, mapping the state to the parameters of the UI component (props), and the latter is responsible for the output logic, that is, mapping the user's operations on the UI component to Action. - mapStateToProps: as a function, mapStateToProps should return an object after execution, where each key-value pair is a mapping.
Accept two parameters, state,ownProps,state. When state is updated, it automatically executes to recalculate the parameters of the UI component, thus triggering the re-rendering of the UI component. OwnProps represents the props object of the container component. If the parameters of the container component change, it will also cause the UI component to re-render, such as the count of the above. - mapDispatchToProps is the second parameter of the connect function, which is used to establish the mapping of the parameters of the UI component to the store.dispatch method. That is, it defines which user's actions should be passed to Store as Action. It can be either a function or an object
Panel
import React, { Component } from 'react'
import Counter from './Counter.js'
const style = {
margin: "20px"
}
class Panel extends Component {
render() {
return (
<div style={style}>
<Counter index="First" />
<Counter index="Second"/>
<Counter index="Third" />
<hr/>
</div>
)
}
}
export default Panel
this is a list.
index.js (entry file)
import React from 'react';
import ReactDOM from 'react-dom';
import './style/index.css';
import Panel from './Component/Panel';
import {Provider} from 'react-redux';
import store from './Redux/Store/store.js'
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
<Provider store={store}>
<Panel/>
</Provider>,<pre>
document.getElementById('root')
);
registerServiceWorker();
React-Redux provides the Provider component, which allows the container component to get the state, avoiding layer by layer downloading. The principle is context. In fact, it is easy to understand that vue has a bus. At this point, the demo of a synchronous redux processing data is complete, so let's talk about async.
Asynchronous
vuex submits Mutation (a bit like git), this thing is synchronous, and it has action here can be synchronous and asynchronous, but redux does not, so here is the emergence of middleware, used to solve asynchronous action, there are several commonly used middleware, here simply write down redux-thunk. The action creator principle is to return a js object, which is handled asynchronously here, and a function is returned, which requires middleware processing.
Modify these two points:
action:
export const Increment = 'increment'
export const Decrement = 'decrement'
export const increment = (counterIndex) => {
return dispatch => {
let asyncAct = {
type:Increment,
counterIndex
}
setTimeout(()=>{ //Send the action in two seconds
dispatch(asyncAct);
}, 2000)
}
}
export const decrement = (counterIndex) => ({
type: Decrement,
counterIndex
})
store:
import {applyMiddleware, createStore} from 'redux'
import thunk from 'redux-thunk'
import reducer from '../Reducer'
const initValue={
'First':1,
'Second':5,
'Third':6
}
const store=createStore(reducer,initValue,applyMiddleware(thunk))
//Using the writing method of middleware to apply Middleware, if there are multiple, pay attention to the order of the middleware inside
export default store
the simple delay of 2s re-counting is complete.
Comments