react-redux ---- 优化项目

使用react-redux

数据渲染和方法提取
方法提取:
index.js:

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

ReactDOM.render(
  <Provider store = {store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

store里面的文件夹之间的关系:
types.js—定义函数的类型:

export const ADD_COUNT = 'add_count'

state.js----定义原始的数据:

const defaultState = {
    count: 1
}
export default defaultState

index.js—引入reducer.js,创建并导出store挂载到全局index.js,并传给App.js,可以套用:

import { createStore, applyMiddleware, compose} from 'redux'

import reducer from './reducer.js'
import thunk from 'redux-thunk'

const componseEnhancers =
  typeof window === 'object' &&
    window._REDUX_DEVTOOLS_EXTENSION_COMPOSE_ ?
    window._REDUX_DEVTOOLS_EXTENSION_COMPOSE_({}) : compose;

const enhancer = componseEnhancers(
  applyMiddleware(thunk),
);

const store = createStore(
  reducer, // 构建初始的数据
  enhancer
)

export default store

reducers.js----原始数据的state由reducer.js来改变,类似于vuex里面的mutations,它主要做的是一些逻辑的处理(把前端传递来的数据与后台的原始数据进行业务逻辑处理):

import defaultState from './state'

import { ADD_COUNT } from './types'

export default (state = defaultState,actions) => {
  // console.log(actions)
  switch (actions.type) {
    case ADD_COUNT:
      let newState = JSON.parse(JSON.stringify(state))
      newState.count +=  actions.value
      // console.log(newState)
      return newState
    default:
      return state;
  }
}

actions.js----返回函数的类型和可能带有的参数,进行数据的请求,然后通过dispatch,将结果传入reducer.js,由reducer.js对state里面的值进行修改:
actions.js

import { ADD_COUNT } from './types'

export const addAction = (value)=>{
  return {
    type:ADD_COUNT,
    value:1
  }
}
export const addItem = ()=>dispatch=>{
  dispatch(addAction())
}

在App.js里面定义方法,
App.js:

import React, { Component } from 'react'
import Com1 from './components/com1'
import {addCountAction} from './store/actionCreators'
import { connect } from 'react-redux'

class App extends Component {
  render() {
    return (   
      <div>
        this is App
        <br />
        store里面的数据---{'>'}{this.props.count}
        <button onClick={this.props.handleClick}>+</button>
        <Com1></Com1>
      </div>
    )
  }
}
const mapStateToProps = (state)=>{
  return {
    count:state.count
  }
}
const mapDispatchToProps = (dispatch)=>{
  return {
    handleClick (){
      dispatch(addCountAction())
    }
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(App)

App.js里面引入的是actions.js俩面导出来的函数名,通过在页面里面定义的函数名经过dispatch调用actions.js的方法,,再通过actions.js里面的方法,将actions.js里面定义的函数名和参数dispatch进reducer.js里面进行,对state=defaultState的默认数据进行修改!
在这里插入图片描述
谷歌浏览器—redux插件
在项目的src目录下创建store,基本结构如:
在这里插入图片描述
数据渲染需要更改的有根目录下的index.js、/store/state.js、/store/reducer.js、App.js
index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as Api from './api/index'
import { Provider } from 'react-redux'
import store from './store'


React.Component.prototype.$http = Api

ReactDOM.render(
  <Provider store = {store}>
    <App />
  </Provider>,
  document.getElementById('root')
);


更改的有


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

相当于给App再次嵌套了一层父元素
/store/state.js:

export var defaultState = {
  title:"待办事项",
  value:'',
  btnText:'ADD',
  arr:[]
}

这里存放的是初始数据

/store/reducer.js

import { GET_TODOS, ADD_ITEM, DEL_TODO,UPDATE_TODO,GET_TODO } from './types.js'

import defaultState from './state'
export default (state = defaultState , actions)=>{
  switch (actions.type) {
    case GET_TODOS:
      // 对state进行深拷贝,将arr重置为请求回来的数据
      let newState = JSON.parse(JSON.stringify(state))
      newState.arr = actions.value.data
      return newState 
    case ADD_ITEM:
      return state
    case GET_TODO:
      return state
    case DEL_TODO:
      return state
    case UPDATE_TODO:
      return state
    default:
      return state
  }
}

数据渲染用到的只有

import defaultState from './state'
export default (state = defaultState , actions)=>{
		....
      return state
}

然后在App.js中使用即可
App.js

....
import { connect } from 'react-redux'
...
render(){
	// 原本没有将数据提取出去之前用的是this.state
    const {title,value,btnText,arr} = this.props
    return(
        <TodoHeader title={title}></TodoHeader>
        <TodoInput value = {value} btnText = {btnText} addItem={this.props.addItem}></TodoInput>
        ...
        )
}
const mapStateToProps = (state)=>{
  return state
}
export default connect(mapStateToProps , mapDispatchToProps)(App)

给App.js添加了一层父元素,只需要在使用的时候调取props就可以了
App.js全部代码

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { TodoHeader, TodoInput, TodoList } from  './components/index'
import { getTodos,addItem,delTodo,getTodo } from './store/actions.js'
class App extends Component {
  constructor(){
    super()
    this.state = {
      title:"待办事项",
      value:'',
      btnText:'ADD',
      arr:[]
    }
  }
  // 生命周期,页面重新加载数据
  componentDidMount(){
    this.props.getTodos()
  }
  render() {
    const {title,value,btnText,arr} = this.props
    return (
      <div>
        <TodoHeader title={title}></TodoHeader>
        <TodoInput value = {value} btnText = {btnText} addItem={this.props.addItem}></TodoInput>
        {
          arr.length === 0 ?
          <p>暂无数据</p> : 
          arr.map(todo=>{
            return <TodoList {...todo} handleDelTodo = {this.props.handleDelTodo} key={todo.id} hanleCompleted ={this.props.hanleCompleted}></TodoList>
          })
        }
      </div>
    )
  }
/**
 * @作用: 删除TODO
 * @参数: id  - 必传
 * @返回值: 
 * @需要注意: 
 */  
  handleDelTodo = (id) => {
    // console.log(id)

    this.$http.delTodo(id)
    // 重新获取一次数据
    this.getTodos()
  }
  /**
   * @作用: 改变input框的选中状态
   * @参数: id ---> 必传
   * @返回值: 
   * @需要注意: 
   */
  hanleCompleted = (id)=>{
    this.$http.getTodo(id).then(res=>{
      var params = res.data
      params.isCompleted = !params.isCompleted
      this.$http.updateTodo(id,params)
      this.getTodos()
    })
  }
}
const mapStateToProps = (state)=>{
  return state
}

const mapDispatchToProps = dispatch=>{
  return {    
    getTodos(){
      dispatch(getTodos())
    },
    
  /**
   * @作用: 添加TODO
   * @参数: params 要添加的数据
   * @返回值: response
   * @需要注意: 
   */
    addItem(result){
      let obj = {
        id : new Date().getTime(),
        title:result,
        isCompleted:false 
      }
      dispatch(addItem(obj))
      dispatch(getTodos())
    },
    handleDelTodo(id){
      dispatch(delTodo(id))
      dispatch(getTodos())
    },
    hanleCompleted(id){
      // console.log(id)
      dispatch(getTodo(id))
    }
  }
}
export default connect(mapStateToProps , mapDispatchToProps)(App)

至此页面数据渲染基本完成,App.js里面除了render函数,其他的都可以去掉,我没去掉是懒得去掉了。。。
gitee.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值