Redux 学习系列(二) —— 实现一个计数器

目录结构:

src |
   -| App.js
   -| index.css
   -| index.js
   views |
     commponents |
       count |
            -| index.jsx
   redux | 
         actions |
                -| count.js
         reducers |
                 -| count.js
         store |
              -| index.js
         -| Constans.js

创建一个 redux 文件夹,分别创建以下文件:

views/redux/store/index.js

/* 
	用于暴露一个store对象,整个应用只有一个store对象
*/

// 引入createStore,专门用于创建redux中最为核心的store对象
import {
    
     createStore } from 'redux'
//引入为Count组件服务的reducer
import countReducer from '../reducers/count'
const store = createStore(countReducer)
//暴露store
export default store

views/redux/Constans.js

/**
  定义action对象中type类型的常量值:便于管理的同时防止程序员单词写错
 */
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

views/redux/reducers/count.js

/* 
  1.创建一个为Count组件服务的reducer,reducer的本质就是一个函数
  2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
*/
import {
    
     INCREMENT, DECREMENT } from '../Constants'

const initState = 0 //初始化状态
export default function countReducer (preState = initState, action) {
    
    
  // console.log(preState);
  // 从action对象中获取:type、data
  const {
    
     type, data } = action
  // 根据type决定如何加工数据
  switch (type) {
    
    
    case INCREMENT: //如果是加
      return preState + data
    case DECREMENT: //若果是减
      return preState - data
    default:
      return preState
  }
}

views/redux/actions/count.js

/**
  为Count组件生成action对象
*/
import {
    
     INCREMENT, DECREMENT } from '../Constants'

export const createIncrementAction = data => ({
    
     type: INCREMENT, data })
export const createDecrementAction = data => ({
    
     type: DECREMENT, data })

views/commponents/count/index.jsx

import  {
    
     Component } from 'react'
//引入store,用于获取redux中保存状态
import store from '../../redux/store/index'
//引入actionCreator,专门用于创建action对象
import {
    
    createIncrementAction,createDecrementAction} from '../../redux/actions/count'

export default class Count extends Component {
    
    

	state = {
    
    }
  // 组件挂载时调用
	componentDidMount(){
    
    
		// 检测redux中状态的变化,只要变化,就调用render,让页面进行渲染
		store.subscribe(()=>{
    
    
			this.setState({
    
    })
		})
	} 

	//加法
	increment = ()=>{
    
    
		const {
    
    value} = this.stepNum
    console.log(value);
		store.dispatch(createIncrementAction(value*1))
	}
	//减法
	decrement = ()=>{
    
    
		const {
    
    value} = this.stepNum
		store.dispatch(createDecrementAction(value*1))
	}
	// 奇数再加
	incrementIfOdd = ()=>{
    
    
		const {
    
    value} = this.stepNum
		const count = store.getState()
		if(count % 2 !== 0){
    
    
			store.dispatch(createIncrementAction(value*1))
		}
	}
  // 偶数再加
	incrementIfEven = ()=>{
    
    
		const {
    
    value} = this.stepNum
		const count = store.getState()
		if(count % 2 == 0){
    
    
			store.dispatch(createIncrementAction(value*1))
		}
	}
	// 异步加
	incrementAsync = ()=>{
    
    
		const {
    
    value} = this.stepNum
		setTimeout(()=>{
    
    
			store.dispatch(createIncrementAction(value*1))
		},500)
	}

	render() {
    
    
		return (
			<div>
				<h1>计数器值为:{
    
    store.getState()}</h1>
				<select ref={
    
    c => this.stepNum = c}>
					<option value="1">1</option>
					<option value="2">2</option>
					<option value="3">3</option>
					<option value="4">4</option>
					<option value="5">5</option>
					<option value="6">6</option>
				</select>&nbsp;
				<button onClick={
    
    this.increment}>+</button>&nbsp;
				<button onClick={
    
    this.decrement}>-</button>&nbsp;
				<button onClick={
    
    this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;
				<button onClick={
    
    this.incrementIfEven}>当前求和为偶数再加</button>&nbsp;
				<button onClick={
    
    this.incrementAsync}>异步加</button>&nbsp;
			</div>
		)
	}
}

修改 App.js

import './assets/css/App.css';
import Count from './views/components/count'
function App () {
    
    
  return (
    <div className="App">
      <Count />
    </div>
  );
}
export default App;

页面效果:
在这里插入图片描述

上面代码是在生命周期钩子中的强制更新,如果需要在每个组件都监听 store,可以在 index.js 入口文件监听 store

修改 views/commponents/count/index.jsx
在这里插入图片描述

扫描二维码关注公众号,回复: 15096154 查看本文章

然后,在 index.js 入口文件中进行设置:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import store from './views/redux/store';

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

// 监听store中值的变化,更新App组件,就不用在每个组件中监听store掉用render了
store.subscribe(() => {
    
    
  ReactDOM.render(
    <App />,
    document.getElementById('root')
  )
})

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

工作流程

  1. 使用函数 createStore 创建 store 数据点;
  2. 创建 reducer,获取 stateaction,生成新的 state
  3. store.dispatch 执行,reducer(preState,action) 处理当前dispatch 后的传入的 action.type 并返回给 preState 处理后的 state
  4. 组件可以通过 storeAPI:store.getState()获取 redux 中的返回值;
  5. store.subscribe() 监听,当 redux 状态变化时,强制更新 render,让页面进行渲染。

猜你喜欢

转载自blog.csdn.net/HH18700418030/article/details/130370480