Note source: Hook Education – big front end employment Training camp
Content: Notes, thoughts and experiences in the process of learning
React Framework Basics 2
Component life cycle
React provides its own lifecycle hook functions
- Component mount phase
- Data update stage
- Component uninstallation phase
Component mount phase
Mount phase: Components are created and inserted into the DOM
Lifecycle approach
- Constructor: Sets the initial configuration of the component – triggered first
- Render: Render the written JSX virtual DOM into a real DOM and render it on the page
- ComponentDidMount: Triggered when the mount is complete
- Examples include AJAX access, event listeners, timers, getting DOM elements, and so on
// Import components
import {Component} from 'react'
/ / App components
class App extends Component {
/ / constructor hook
constructor() {
console.log('Constructor executes')
/ / inherited Component
super(a)// Set the initial state
this.state = {
num: 0
}
// Change the function pointing
this.clickBtn = this.clickBtn.bind(this)}// Button click function. Specifically, the arrow function is not used here, so this points to unnifinder, but constructor can be modified
clickBtn() {
console.log(this)}/ / render hook
render() {
console.log('Render executes')
return (
<div>} {this.state.num} {/* button */}<button onClick={this.clickBtn}>Click on the</button>
</div>)}// Execute the componentDidMount hook function once the mount is complete
componentDidMount() {
console.log('componentDidMount executes')
/ / timer
setInterval(() = > {
Num +1 every 1 second
this.setState({num: this.state.num +1})},1000)}}/ / export
export default App
Copy the code
Component update phase
Update components: Components need to be re-rendered when data changes, such as externally passed props and state data
Related lifecycle hooks
- ShouldComponentUpdata (nextProps, nextState) : Returns a Boolean value to determine whether the component is updated
- Render: As above, render the JSX virtual DOM into the real DOM
- ComponentDidUpdate: Similar to the above, called after the component is updated
// Import components
import {Component} from 'react'
/ / App components
class App extends Component {
constructor() {
super(a)this.state = {
num: 0
}
this.clickBtn = this.clickBtn.bind(this)}clickBtn() {
this.setState({num: this.state.num + 1})}/ / render hook
render() {
console.log('Render executes')
return (
<div>
{this.state.num}
<button onClick={this.clickBtn}>Click on the</button>
</div>)}// shouldComponentUpdate hook - Update the first execution
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdata executed ')
return true
}
// componentDidUpdate hook - Updated after execution
componentDidUpdate() {
console.log('componentDidUpdate executed ')}}/ / export
export default App
Copy the code
ShouldComponentUpdate is executed before the component is updated, and must return a Boolean value to determine whether the component is updated or not. If false is returned, the component does not proceed with subsequent Render and componentDidUpdate hooks
- ShouldComponentUpdate; shouldComponentUpdate; shouldComponentUpdate; shouldComponentUpdate; shouldComponentUpdate; shouldComponentUpdate
- In React, however, this is no longer recommended. Instead, you can use PureComponent instead of Component to create class components
Component uninstallation phase
Component unload: Component is removed from the DOM
Related lifecycle hooks
- ComponentWillUnMount: Executed before the component is unmounted
For example, if we set event listening seconds in a component, this time may still exist after the component is removed, so we can consider removing the listener before uninstalling it. The same goes for timers and AJAX
An AJAX request
React has its own AJAX request method, so it needs to use a third-party library such as Axios
// Import components
import {Component} from 'react'
// Introduce AXIos for AJAX requests
import axios from 'axios'
/ / App components
class App extends Component {
constructor() {
/ / inherited Component
super(a)// Set the state
this.state = {
message: ' '}}// Render method
render() {
return (
// Bind state data, there is no data at initialization
<p>The result of the data request is: {this.state.message}</p>)}// After the component is mounted, async is used for synchronous processing
async componentDidMount() {
// Call the interface to get data
const {data} = await axios.get('http://edufront.lagou.com/front/ad/getAdList')
// Pass the data to the state data
this.setState({message: data.message})
}
}
/ / export
export default App
Copy the code
Forward requests
To take advantage of the fact that there is no cross-domain problem between servers, clients who want to request cross-domain data can use the same-origin server to send the request to get the data
React Forwards requests
-
Json, add the proxy field, and write the requested server address at the end. Note that proxy only needs to write the server address, and how to write the specific function suffix. If there is no such suffix on my server, it will automatically find the proxy server, but only one server address can be configured
// Add the cross-domain address "proxy": "Http://edufront.lagou.com or http://localhost:3005 (teacher)" Copy the code
When the program reaches this step, it will first try to obtain data from the homologous server. When the homologous server fails to obtain data, it will use the proxy server set above to obtain data async componentDidMount() { / / set the proxy, so direct route can write here, otherwise will be written in http://edufront.lagou.com/front/ad/getAdList const {data} = await axios.get('/front/ad/getAdList') this.setState({message: data.message}) } Copy the code
-
Install http-proxy-Middleware and create a new setupproxy.js file. Again, you don’t need to write prefixes to get data
/ / incoming HTTP proxy -- middleware const { createProxyMiddleware} = require('http-proxy-middleware') // Export the configuration module.exports = app= > () { / / when the program is found '/ front will automatically use http://edufront.lagou.com app.use('/front', createProxyMiddleware({ // Forwarding address target: 'http://edufront.lagou.com'.// Enable cross-domain changeOrigin: true}}))Copy the code
There is no practice because there is no server for teachers
Mock/Mock data
In general, the front-end and back-end are developed together, so there may be no back-end interface for us to use when we want to use the interface in the program, so we can define some virtual data for development and debugging, and the interface development is completed in the later period only need to be replaced
steps
- Directory public/ pathname/interface name. json Creates a file
- The component calls the get method using AXIos to get the interface file
// public/ API /student.json create mock data to simulate some student data[{"id": "0"."name": "zs"."age": 19."sex": "Male"},
{"id": "1"."name": "ls"."age": 20."sex": "Female"},
{"id": "2"."name": "ww"."age": 19."sex": "Male"},
{"id": "3"."name": "zl"."age": 17."sex": "Female"},
{"id": "4"."name": "ll"."age": 22."sex": "Male"}]Copy the code
// SRC/app.js components use interfaces
import {Component} from 'react'
// Introduce AXIos for AJAX requests
import axios from 'axios'
/ / App components
class App extends Component {
constructor() {
super(a)// Initialize the state data
this.state = {
// Student list
students: []}}// Get data
getData = async() = > {Public is the root directory of the package
const {data} = await axios.get('api/student.json')
// Use data
this.setState({students: data})
}
render() {
return (
<div>{/* button: Click get data */}<button onClick={this.getData}>To get the data</button>
<ul>} {this.state.students. Map (item => () {this.state.students.<li key={item.id}>
<span>. Name: {item name}</span>
<span>Age: {item. Age}</span>
<span>Gender: {item. Sex}</span>
</li>
))}
</ul>
</div>)}}export default App
Copy the code
Note: This approach only virtualizes GET requests
Redux
The working process
- Similar to Vue’s Vuex, Redux is a data management framework that provides a store unified data storage repository
- The Store acts as a middleman for data management, eliminating the need for direct data transfer between components
Create a Store and reducer
- Install the redux and React-redux NPM packages
- Get the createStore method in redux from index.js
- Use this method to create a store repository, passing in the reducer function as a parameter
- Reducer is a function that returns an object, inside which is data
- The reducer function does not need to be written in index or called reducer. It is usually an independent JS file
Import React from 'React 'import ReactDOM from 'react-dom'import App from './App'// Import {createStore} from 'redux'// Introduce a reducer function (it is recommended to write the reducer function in a separate file) import reducer from './redux/num'// Reducer () {// return {// num: // create store, Const store = createStore(reducer) console.log(store.getstate ()) reactdom.render ()
, document.getElementById('root'))
Copy the code
// SRC /redux/num. Js Create a reducer file, which is recommended and easy to manage. Export default () => {return: 0}}
Copy the code
Get Store data
- Introduce the react-redux Provider method in index
- Use the Provider as a component to wrap the App component and pass the store created in the previous part to the App as a parameter. In this case, the App contains the props store data
- Introduce the Connect method in React-Redux to components that use store data
- Then export connect ((store) => ({data to use}) directly below, which can be static or store data
// SRC /index.js react-redux method, Import React from 'React 'import ReactDOM from' React -dom'import app from './ app '// import the store import method {createStore} from 'redux'// Introduce a reducer function (it is recommended to write the reducer function in a separate file) import reducer from './redux/num'// Add Provider to storeImport {Provider} from 'react-redux' Const store = createStore(reducer) console.log(store.getstate ()) reactdom.render ()
{/* Use Provider to pass store to App, */}
, document.getelementById ('root'))
Copy the code
Import {connect} from 'react-redux'function num (props) {// SRC /components/num. Console. log(props) return (props {props. Num}
)} // PropsConst toData = (store)=>({// Can be store data num: Num, // can also be static data (usually dynamic) a:1, b:2})// Export data can be modified // finally export a function // then run directly, The argument is the object to use export Default Connect (toData)(Num)
Copy the code
Modifying Store data
- When you want to modify the store data, you can trigger the Dispatch method in props (which is passed when the Store passes data) and pass in an internal object. Inside the object is set the type attribute, which is called the reducer method to be triggered to modify the data
- The second parameter is allowed to be accepted in the Reducer, and the second parameter is a string. The reducer function uses the swith statement to judge this parameter and performs different methods to recover different values
// SRC /components/num.js calls the props dispatch method, Import {connect} from 'react-redux'function Num(props) {return (
{/* Call the Dispatch method in props (which connect added automatically to modify the corresponding data) and pass in an object,
)} Propsconst toData = (store)=>({// Can be store data num: Num, // can also be static data (usually dynamic) a:1, b:2})// Export data can be modified // finally export a function // then run directly, The argument is the object to use export Default Connect (toData)(Num)
Copy the code
// SRC /redux/num. // The first parameter is still the data, but uses the default data, the second parameter is the action to be performed, Export default (data= myData, fnName) => { Check the value of the type attribute. Switch (fnname.type) {// addNum case 'addNum': // directly return to modify data return {num: data.num + 1} case 'reduceNum': Return {num: data.num - 1} // If no action is performed, data is returned. Default: return data}}
Copy the code
Extract action code as a function
Transform The Dispatch using the second parameter of CONNECT
Import {connect} from 'react-redux'function Num(props) {console.log(props) return (
{/* Let's separate out the action,
{props onClick={props.reduceNum}>-
)}const toData = (store)=>({ num: Const action = dispatch => ({// there are various methods inside the object, AddNum () {dispatch({type: 'addNum'})}, reduceNum() {dispatch({type: Dispatchexport default connect(toData, action)(Num)
Copy the code
Action pass parameters
{props.num}
Copy the code
{/*
*/}
{props. Num}
Const action = dispatch => ({// there are various methods inside the object. 'addNum'}) }, addNum_n(payload) { dispatch({type: 'addNum_n', payload}) }, reduceNum() { dispatch({type: 'reduceNum'}) }})
Copy the code
Automatically generate action trigger functions
Borrowing from redux’s bindActionCreators function, which takes in two parameters, the first is an object and the second is Dispatch, the Action is automatically assembled by providing the method name and type, for example
// Introduce the connect method import {connect} from 'react-redux'// introduce the bindActionCreatorsfangfa automatic assembly actionImport {bindActionCreators} from 'redux'function Num(props) { console.log(props) return (
{props.num}
)} Const toData = (store)=>({num: store.num})const Action = dispatch =>({// bindActionCreators returns an object, which we expand here... BindActionCreators ({// Write the method name addNum() {// Return the dispatch parameter. 'addNum'} }, addNum_n(payload) { return {type: 'addNum_n', payload} }, reduceNum() { return {type: 'reduceNum'} } }, dispatch)})export default connect(toData, action)(Num)
Copy the code
The first parameter of bindActionCreators can be packaged separately
// SRC /redux/ numaction.js // Encapsulate the first parameter of bindActionCreators separately and export all the methods export const addNum = () => ({type: 'addNum'})export const addNum_n = (payload) => ({type: 'addNum_n', payload})export const reduceNum = () => ({type: Export default {addNum: () => ({type: 'addNum'}), addNum_n: (payload) => ({type: 'addNum_n', payload}), reduceNum : () => ({type: 'reduceNum'})}
Copy the code
Import {connect} from 'react-redux'// SRC /components/num BindActionCreatorsfangfa automatically assembers actionImport {bindActionCreators} from 'redux'// Introduces separately packaged bindActionCreators parameters, Import and rename import *as numAction from '.. /redux/numAction'function Num(props) { console.log(props) return (
{props.num}
)}const toData = (store)=>({ num: Store. Num})const Action = dispatch => ({// bindActionCreators returns an object, which we expand here // Put the separately encapsulated object into the first parameter... bindActionCreators(numAction, dispatch)})export default connect(toData, action)(Num)
Copy the code
Action type constant
We have set some strings in the Action and Reducer. We can package these strings separately into a module for management, and direct replacement can be introduced when using them
// SRC /redux/ numtype.js create a new js file and export constants // store strings using constant. Export const ADDNUM = 'ADDNUM 'export const ADDNUM_N =' ADDNUM_N 'export const REDUCENUM = 'REDUCENUM '// Use constants for other files Introduce steady on and use import {ADDNUM, ADDNUM_N, REDUCENUM} from './Numtype'
Copy the code
Reducer Split and merge
Reducer is responsible for obtaining store data and then operating the data according to the instructions
- When the whole project has multiple components, each of which has its own data to be stored in the store, it will be complicated to use a reducer. Js file to manage, so Redux allows us to split the data to be used by all components into multiple reducer
- The combineReducers of Redux can combine two split reducers and export them into one object
- At this point, the data structure of the call will be different from before, multiple data will become properties under the store, and the actual data will be used inside
Redux whole small Demo
Here I’m going to go through the whole Redux
Project directory
Compements component directory
Import {connect} from 'react-redux' import {connect} from 'react-redux Importing bindActionCreators is used to automatically generate Actionimport {bindActionCreators} from 'redux'// Importing the first bindActionCreators parameter import that is individually encapsulated CountAction from '.. // function Count(props) {return (<> {/* +1, +5, -1, and -- 5 */} {/* bindActionCreators will automatically generate the Action command based on the configuration and give it to the props. To pass the parameters, < buttonclick ={() => props. AddCount (1)}>+1
props. AddCount (5)}>+5
{/ * * / display the current data} < p > {props. Count} < / p > < button onClick = {() = > props. AddCount (1)} > 1 < / button > < button onClick = {() = > )}// myData = (store) => ({count: props. AddCount (-5)}>-5 ) Countreducer.count})// Call bindActionCreators to automatically generate the Action directive Const myAction = dispatch => ({// Note that you need to pass in the dispatch here... BindActionCreators (CountAction, Dispatch)})// Export the component and call the connect function, Export Default Connect (myData, myAction)(Count) was automatically generated using bindActionCreators.
Copy the code
/ / SRC/Components/Student. Js Student list component / / call the connect to get data and inject Components import} {connect the from 'react - redux' / / The bindActionCreators method was introduced to automatically generate the Action directive import {bindActionCreators} from 'redux'// to introduce the separately encapsulated bindActionCreators first parameter import Actoin from '.. /Store/Action/Student'// Module function Student(props) {return (<> {/* Click on the back button to add an app to the data, which can be called directly after the bindActionCreators command is generated.
{ Present student list * /} {props. Students. The map (item = > {return (< li key = {item. Id} > {item. The name} < / li >)})} < / ul > < / a >)} / / connect the first parameter - Const myData = (store) => ({students: Array. StudentReducer})// connect Second parameter - auto generate Actoin directive const action = dispatch => ({... BindActionCreators (Actoin, Dispatch)})// Export the app, which uses Connect to inject data and instructions into the app export Default Connect (myData, Action)(Student)
Copy the code
Store – Instruction directory
/ / SRC/Store/Action/Count. / / js accumulator instructions introduced quantitative string often import {ADDCOUNT} from '.. /ActionType/Count'// The first parameter for bindActionCreators const Action = {addCount(num) {return {type: ADDCOUNT, num}}}// Export export default Action
Copy the code
/ / SRC/Store/Action/Student. Js Student list instruction / / introducing quantitative string often import {ADDSTUDENT} from '.. /ActionType/Student'// The instructions for the first parameter of bindActionCreators const Action = {addStudent(newInfo) {return {type: ADDSTUDENT, newInfo}}// Export default Action
Copy the code
Store/ActionType usually quantifies strings
/ / SRC/Store/ActionType/Count. Js counter / / often quantitative string export const ADDCOUNT = 'ADDCOUNT' / / SRC/Store/ActionType/Student. / / js Student list Export const ADDSTUDENT = 'ADDSTUDENT'
Copy the code
Store/Reducer Warehouse data and behavior catalog
/ / SRC/Store/Reducer/Count. Js accumulator behavior and data / / introducing quantitative string often import {ADDCOUNT} from '.. /ActionType/Count'// Count component data const myData = {Count: Const CountReducer = (data = myData, const CountReducer = (data = myData, Switch (action.type) {// add case ADDCOUNT: // Return data return {count: Data. count + action.num} // Export raw data default: return data}}// Export default CountReducer
Copy the code
/ / SRC/Store/Reducer/Student. / / js Student list data and behavior introduced quantitative string often import {ADDSTUDENT} from '.. /ActionType/Student'// Const myData = [{id: 0, name: Parameter 1 - Data to be exported // Parameter 2 - Data to be generated const StudentReducer = (data = myData, Action) => {switch (action.type) {case ADDSTUDENT: return [...data, action.newinfo] Return data}}// Export default StudentReducer
Copy the code
/ / SRC/Store/Reducer/index. The merger of js split writing data and behavior / / introduce combineReducers used to merge Reducerimport {combineReducers} from 'story' / / Introduce two separately written Reducerimport CountReducer from './Count'import StudentReducer from './Student'// Directly export the merged Reducerexport default combineReducers({ CountReducer, StudentReducer})
Copy the code
App component
Import {Component} from 'react' import Count from './Components/Count'import Student from ' '. / Components/Student / / component, Class App extends Component {render() {return (
)}}// Export default App
Copy the code
Index. Js components
src/index.jsimport React from 'react'import ReactDOM from 'react-dom'import App from './App'Storeimport {createStore} from 'redux'// Introduce the merged Reducerimport Reducer from './Store/Reducer/index'// Introduce Provider pass data to Appimport {Provider} from 'react-redux'// Create repository const Store = CreateStore (Reducer) reactdom.render (
{/* Use Provider to wrap App to pass data to App */}
, document.getElementById('root'))
Copy the code
Redux workflow review
- Create a Store data warehouse to save data and associate the reducer with the reducer
- Initial data and instruction functions are saved internally by the Reducer, and new data is returned to the store after the instruction is executed
- Use the provider to pass the store backwards
- The connect method is used to obtain data from the Store on a specific component, which is passed to the props of the component, and a Diapatch method is added to call the reducer related instruction behavior
- Access the data through the props of the component, and then render it on the interface
- If you want to modify data, you can trigger the dispatch method of props and pass the instructions and data to the Reducer for processing
- Data is updated by the Reducer according to the instructions, which is returned to the Store, which in turn is passed to the component
Redux code optimization
- Reducre can be divided and written, and finally dumped into the store as long as the combineReducers can be combined
- If you want to simplify the unification, call the instructions as a separate Action function, and the Action can be automatically generated through bindActionCreators
- You can define the Action directive as a constant (I don’t think you need it)
Redux middleware
- From the code level, middleware is a function. When the component wants to modify the data, it first triggers the instruction, which passes through the middleware and then passes to the store. Previously, the instruction was directly passed to the Store
- Middleware can be registered using Redux’s applyMiddleware, which is performed on the second parameter of cerateStore
- The purpose of the middleware is to intercept instructions, perform some asynchronous operations at this time, and still deliver instructions to the Store after completion
import React from 'react'import ReactDOM from 'react-dom'import App from './App'Import {createStore, ApplyMiddleware} from 'redux' 'zs'}// reducerfunction reducer(data = state, Action) {// Print console.log(action) // return data return state}// middleware - itself a function // argument 1-store getState method, 2 - Reducer dispatch method Function middel({getState, dispatch}) {// Print two arguments look at console.log(getState(), Dispatch) // Middleware layer 2 function // parameter is a method, Return function(next) {return function(action) {setTimeout(() => { Console. log(' middleware async operation performed ') console.log(action) // Execute async operation to store next(action)}, 1000)}}} Const store = createStore(Reducer, applyMiddleware(middel)) const store = createStore(reducer, applyMiddleware(middel)) 'add'})ReactDOM.render(
, document.getElementById('root'))
Copy the code
Redux-thunk Asynchronous solution
Reducer is responsible for calculation and is not suitable for asynchronous operations. Therefore, we can use redux-thunk to handle asynchronous operations that need to be processed
Import React from 'React 'import ReactDOM from 'react-dom'import App from './App'import {createStore, applyMiddleware} from 'redux' Register middleware import {createStore, ApplyMiddleware} from 'redux'// Get the reducerImport reducer to use from './store/reducer'import {Provider} from 'react-redux'// Import thunk from 'redux-thunk' const store = createStore(reducer, applyMiddleware(thunk))ReactDOM.render(
, document.getElementById('root')
Copy the code
// SRC /store/action/text.js use thunk middleware for asynchronous processing // import axios for asynchronous request import axios from 'axios' // getData directive, this directive is a virtual directive, has no real meaning, Thunk getData() {// returns a function async (dispatch) => {// functions use async and await to getData const {data} = Await axios. Get (' http://edufront.lagou.com/front/ad/getAdList ') / / get the data after a successful call dispatch trigger another command dispatch ({type: 'addType', newDate: [data.message]}) } }}export default action
Copy the code
Redux-saga asynchronous solution
- Like Redux-Thunk, redux-Saga can also perform asynchronous request operations and is also a middleware solution to the complex Action writing problems caused by Redux
- Saga is introduced as a function that needs to be executed once before it can be used as middleware
- Saga supports writing asynchronous requests separately: Use takeEvery (instruction) and Put (diapatch) in Redux-saga/Effects
- The method for saga in index to receive the export of saga files written separately
Import React from 'React 'import ReactDOM from 'react-dom'import App from './App'// CreateStore creates a store repository ApplyMiddleware import {createStore, ApplyMiddleware} from 'redux'// Get the reducerImport reducer to use from './store/reducer'import {Provider} from 'react-redux'// Redux-sagaimport reduxSaga from 'redux-saga' import getData from './store/saga/text.saga'// Const saga = reduxSaga() Const store = createStore(Reducer, Run (getData) reactdom. render(
, document.getElementById('root'))
Copy the code
// SRC /store/action/text.js create a dummy directive to capture saga // with saga the action is written in the normal way const action = {// getData(){return {type: 'getData'}}}// Export default Action
Copy the code
Import {connect} from 'react-redux'import {bindActionCreators} from 'redux'import action from '.. /store/action/text'function Text(props) { console.log(props) return ( <>
Copy the code
/ / SRC/store/saga/text. The new saga saga. Js files separate request data / / introduction saga of two methods to capture / / takeEvery instruction / / put the equivalent of dispatchimport {takeEvery, } from 'redux-saga/effects' import axios from 'axios' Also use special writing function * loaderData () {/ / get data const {data} = yield axios. Get (' http://edufront.lagou.com/front/ad/getAdList ') Yield PUT ({type: 'upData', data: Data.content})} Export default function* getData() {// Yield is equivalent to return. Yield takeEvery('getData', loaderData)} takeEvery('getData', loaderData)} takeEvery('getData', loaderData)}
Copy the code
/ / SRC/store/reducer/text, js reducer for you just need to write new instruction function / / raw data let text = [{id: 1, name: }]// const textReducer = (state = text, action) => {switch (action.type) { Case 'upData': return [...action.data] default: return state}} export default textReducer
Copy the code
Redux-saga split and merger
We need to use the split and merge features of Saga when there are multiple saga requirements
- Saga/Effects provides an all method for merging multiple Sagas
- And then finally index. Replace saga’s run method with the merged rootSaga
import {all} from 'redux-saga/effects'Import multiple Sagaexportsdefault function* rootSaga(a){ yieldAll ([multiple saga () execute])}Copy the code
Simplify actions and Reducers
Actions and Reducers are simplified using the Redux-Actions package
/ / SRC/store/Action/Action count. Js Action files use createAction method instructions all output / / introducing the createAction output import from {createAction} Redux-actions export const addCount = createAction('addCount')export const cutCount = createAction('cutCount')export const addCount_N = createAction('addCount_N')
Copy the code
/ / SRC/store/Reducer Reducer. Count. Js / / introduce handleActions method simplify the Reducer, Reducerimport {handleActions as reducer} from 'redux-actions'// Introduce the required directives, Import {addCount, addCount_N, cutCount} from '.. /Action/action.count'const data = { count: Const countReducer = reducer({// Each attribute inside the object is the directive name, the attribute value is a function, this function returns an object, [addCount]: (state, action) => ({count: Payload [addCount_N]: (state, action) => ({count: state.count + action.payload}), [cutCount]: (state, action) => ({count: State.count-1})}, data) export default countReducer
Copy the code