数据渲染和方法提取
方法提取:
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