Hello, brave friends, I am your strong mouth king xiao Wu, healthy body, not brain disease.
I have a wealth of hair loss techniques that will catapult you to the top.
A look will be written waste is my theme, food to pick the foot is my characteristics, humble in showing a trace of strong, stupid people have stupid blessing is the greatest comfort to me.
Welcome to The use and principles of Redux in React Hook.
Introduction to story
What, why and how to Redux
The first to ask what❓What is the story
When a Web application is split into a view layer and a data layer, a Redux is a container that holds its data, essentially maintaining an object that stores the data.
- State: a container (an object) that holds data
const initState = {
count: 0,}Copy the code
- Action: a want to do process (plan what kind of operation to do)
ActionType
Is theAction
The description is also the connectionAction
andReducer
The bridge- It’s essentially a function of
ActionType
andpayload
(data) composed of objects
export const increaseConstant = 'INCREASE' // ActionType
{
type: increaseConstant,
payload,
} // Action
Copy the code
- Reducer: a to do process (Action plan execution)
case increaseConstant: // when ActionType is 'INCREASE', count++ is executed
return {
...state,
count: payload + 1
}
Copy the code
The second question according to❓Why use Redux
When you don’t know if you need to useRedux
It is not necessary to use.
The following set of GIFs is a good illustration of how an application is developed and when Redux is needed. Photo source and original link
- In the early stages of the game, data is passed from parent to child
- In the middle of the game, there are a few non-parent components that need to communicate some data
- As the game enters its later stages, it begins to require a lot of data traffic
- In this case, it is
Redux
Where you can use it. Use itRedux
The subsequent process is as follows
How to❓How to use Redux
Before we talk about how to use it, let’s simulate a Redux process from start to finish. Once you understand how it works, it’s not a piece of cake.
Let’s go, come on baby!
Let’s use a simple counter example to simulate the implementation of a Redux:
Create a count component
import React, { useState } from 'react'
const CountItem = (props) = > {
const {
count,
increase,
} = props
return (
<>
{count}
<button onClick={increase}>Count++</button>
</>)}const Count = () = > {
const [count, setCount] = useState(0)
const increase = () = > {
setCount(count + 1)}return (
<CountItem
count={count}
increase={increase}
/>)}export default Count
Copy the code
Now we want to wrap the operation on the data as a method called Dispatch, passing an Action format: {type: XXX, payload: XXX}
Encapsulates a Dispatch function
const dispatch = (action) = > {
switch(action.type) {
case 'INCREASE':
return action.payload + 1
default:
break}}Copy the code
Rewrite the increase method
const increase = () => {
- setCount(count + 1)
+ setCount(dispatch({type: 'INCREASE', payload: count}))
}
Copy the code
At this point, we will also pull out the action object, easy to reuse, new action.js.
Action.js => Returns the Action object
const increaseCount = (payload) = > {
return {
type: 'INCREASE',
payload
}
}
Copy the code
Rewrite the increase method
const increase = () => {
- setCount(dispatch({type: 'INCREASE', payload: count}))
+ setCount(dispatch(increaseCount(count)))
}
Copy the code
Next, we will remove the event operations from the dispatch to the reducer and create the reducer.js.
Js => Perform data operations on reducer
const reducer = (state, action) = > {
const { type, payload } = action
switch(type) {
case 'INCREASE':
return {
...state,
count: payload + 1
}
default:
return state
}
}
Copy the code
Rewrite dispatch function
const dispatch = (action) => {
const state = {
count,
}
const newState = reducer(state, action)
return newState
}
Copy the code
Rewrite the increase method
const increase = () => {
- setCount(dispatch(increaseCount(count)))
+ setCount(dispatch(increaseCount(count)).count)
}
Copy the code
Next, we’ll take the set method to the Dispatch, and we’ll have everything done in the Dispatch.
Continue modifying the Dispatch function, adding setters to do the mapping
const dispatch = (action) => {
const state = {
count,
}
+ const setter = {
+ count: setCount
+}
const newState = reducer(state, action)
+ for (let key in newState) {
+ setter[key](newState[key])
+}
- return newState
}
Copy the code
Rewrite the increase method
const increase = () => {
- setCount(dispatch(increaseCount(count)).count)
+ dispatch(increaseCount(count))
}
Copy the code
As we can see here, action.type is the bridge between action and Reducer. We can define actionType as a constant and save it separately.
Add actionType to action
export const increaseConstant = 'INCREASE'
// Replace 'INCREASE' in action and Reducer with increaseConstant
Copy the code
Based on the existing scenario, if we have another function, but the current reducer cannot help us to divide different functions well, let’s transform the reducer into an object, and use the key of the object to distinguish functions.
Rewrite the reducer
const reducer = {
count(state, action) {
const { type, payload } = action
switch(type) {
case increaseConstant:
return payload + 1
default:
break}}},Copy the code
In this case, we need to traverse the Reducer and find the correct key so that the program can be executed correctly. We create combInereducers.js to complete this operation.
combineReducers
const combineReducers = (reducer) = > {
return (state, action) = > {
let ret = {}
for (let key in reducer) {
ret[key] = reducer[key](state[key], action)
}
return{... state, ... ret, } } }Copy the code
Continue to change the dispatch function to support the current format reducer.
Rewrite the dispatch
- const newState = reducer(state, action)
+ const newState = combineReducers(reducer)(state, action)
Copy the code
At this point, a redux implementation is complete. Next, let’s actually use redux. In fact, when the above operation is done, how to use it has already said about.
Redux + React
The action, Reducer, and Count components are the same as above. The Count component needs to be simply rewritten.
The new store. Js
import { createStore, combineReducers } from 'redux'
import reducer from './recuder'
const initState = {
count: 0,}const store = createStore(
combineReducers(reducer),
initState,
)
export default store
Copy the code
Create app.jsx and introduce the Store
import { Provider } from 'react-redux'
import store from './store'
const App = () = > {
return (
<Provider store={store}>
<Count />
</Provider>)}export default App
Copy the code
Overwrite the Count component
import React from 'react'
import { connect } from 'react-redux'
import { increaseCount } from './action'
const CountItem = (props) = > {
const {
count,
increase,
} = props
return (
<>
{count}
<button onClick={increase}>Count++</button>
</>)}const Count = (props) = > {
const {
count,
dispatch,
} = props
const increase = () = > {
dispatch(increaseCount(count))
}
return <CountItem count={count} increase={increase} />
}
export default connect(
(state) = > {
return state
},
(dispatch) = > {
return { dispatch }
}
)(Count)
Copy the code
Next, let’s rewrite it as hook
Overwrite the Count component
import React from 'react'
- import { connect } from 'react-redux'
+ import { useSelector, useDispatch } from 'react-redux'
import { increaseCount } from './action'
const CountItem = (props) => {
const {
count,
increase,
} = props
return (
<>
{count}
<button onClick={increase}>Count++</button>
</>
)
}
const Count = () => {
- const {
- count,
- dispatch,
- } = props
+ const count = useSelector(state => state.count)
+ const dispatch = useDispatch()
const increase = () => {
dispatch(increaseCount(count))
}
return <CountItem count={count} increase={increase} />
}
- export default connect(
- (state) => {
- return state
-},
- (dispatch) => {
- return { dispatch }
-}
- )(Count)
+ export default Count
Copy the code
That’s the end of this article, and you can write a more complex component exercise, such as todoList, manually funny. I’m going to Timi. My little buddy is waiting for me to take him to the silver. A bunch of bastards.