Redux = Reducer+Flux
- React 注重的是视图,对于数据传递,不好友好,繁琐,性能低下。所以需要有配套的技术。先有Flux后升级,才有Redux。
- 数据层框架,数据存储在Store中
Redux Flow
先安装Redux插件 Redux DevTools
实际操作的时候要在打开会怎样
点进去,有配置文档,基础的,在你项目代码中只要配一行,深入了解的话,你可以仔细看看
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
用的antd库,自己可以根据实际情况选择
主要是样式问题,因为css-moudle模块化了(我之前博客写过),我是在index.html引用全局样式的。如果有什么更好的方案,欢迎大佬留言。
列表信息和输入框初始数据呈现
1.按照依赖
npm i redux -D
2.创建一个文件夹
reducer.js
// 存储具体数据的
const defaultState ={
inputValue:"123",
list:[
'Racing car sprays burning fuel into crowd.',
'Japanese princess to wed commoner.',
'Australian walks 100km after outback crash.',
'Man charged over missing wedding girl.',
'Los Angeles battles huge wildfires.',
]
}
export default (state = defaultState,action) =>{
return state
}
index.js
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store;
而在目标文件
import store from './store/index.js'
constructor(props) {
super(props)
// console.log(store.getState())
this.state = {
data:store.getState()
}
//打印如下
// console.log(this.state.datat,"test")
}
// 所有reducer保存的数据都在 store.getState(),只是重新赋值给this.state中 data
<div style={{width:400,margin:20}}>
<div style={{display:"flex"}}>
<Input placeholder="Basic usage"
style={{marginRight:20}}
value={this.state.data.inputValue}
/>
<Button type="primary">提交</Button>
</div>
<List
bordered
style={{marginTop:10,width:"300"}}
dataSource={this.state.data.list}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>,
</div>
修改store中数据
在这里我只实时改变input中的值
主要是创建action ,把action的type和要改变的值给 store reducer.js,来判断,修改数据。当然每个人文件格式不一样。此入门,实际项目要模块化,还有好多type类。
注意:
就如同一开始流程图显示,store没有改变原始state值,而是深度拷贝一份出来,修改值,返回newState,从而更新。所以,用redux,数据更改,只有Store中可以改变,不能在React Component中。我把三个文件内容全都附上
TodoList.js
import React, { Component } from 'react'
import { Input,Button, List} from 'antd';
import store from './store'
export default class TodoList extends Component {
constructor(props) {
super(props)
console.log(store.getState())
this.state = {
data:store.getState()
}
console.log(this.state.data,"test")
this.handleStoreChange=this.handleStoreChange.bind(this);
//store中有数据只要跟新,subscribe就自动调用handleStoreChange 方法
store.subscribe(this.handleStoreChange);
}
handleInputChange(e){
const action = {
type:"change_inputValue",
value:e.target.value
}
// action 推送给reducer.js type和改变数值
store.dispatch(action)
}
handleStoreChange(){
this.setState({
data:store.getState()
})
console.log('store chnage',store.getState())
}
render() {
return (
<div style={{width:400,margin:20}}>
<div style={{display:"flex"}}>
<Input placeholder="Basic usage"
style={{marginRight:20}}
value={this.state.data.inputValue}
onChange={this.handleInputChange.bind(this)}
/>
<Button type="primary">提交</Button>
</div>
<List
bordered
style={{marginTop:10,width:"300"}}
dataSource={this.state.data.list}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>,
</div>
)
}
}
index.js
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store;
reducer.js
const defaultState ={
inputValue:"123",
list:[
'Racing car sprays burning fuel into crowd.',
'Japanese princess to wed commoner.',
'Australian walks 100km after outback crash.',
'Man charged over missing wedding girl.',
'Los Angeles battles huge wildfires.',
]
}
export default (state = defaultState,action) =>{
// state 整个数据()
// action
// reducer 可以接受state,但不能修改state
if(action.type==='change_inputValue'){
const newState = JSON.parse(JSON.stringify(state))
newState.inputValue=action.value
return newState
}
console.log(state,action,"_____")
return state
}
添加列表
//TodoList.js
handleSubmit(){
const action ={
type:"add_todo_item"
}
store.dispatch(action)
}
<Button type="primary" onClick={this.handleSubmit.bind(this)}>提交</Button>
// reducer.js
if(action.type==='add_todo_item'){
const newState = JSON.parse(JSON.stringify(state))
newState.list.push(newState.inputValue)
newState.inputValue=""
console.log(newState,"newState")
return newState
}
删除列表
handleDeleteItem(index){
const action ={
type:"delete_item",
index
}
store.dispatch(action)
}
<List
bordered
style={{marginTop:10,width:"300"}}
dataSource={this.state.data.list}
renderItem={(item,index) => (<List.Item onClick={this.handleDeleteItem.bind(this,index)}>{item} </List.Item>)}
/>,
if(action.type==='delete_item'){
const newState = JSON.parse(JSON.stringify(state))
newState.list.splice(action.index,1)
//console.log(action.index)
return newState
}
小结
createStore:创建store
const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
store.dispatch:派发action
const action ={
type:"add_todo_item"
}
store.dispatch(action)
store.getState:获取store中所有数据内容
// console.log(store.getState())
this.state = {
data:store.getState()
}
console.log(this.state.data,"test")
this.handleStoreChange=this.handleSt
store.subscribe:订阅store,数据一改变,即触发方法,刷新数据
this.handleStoreChange=this.handleStoreChange.bind(this);
//store中有数据只要跟新,subscribe就自动调用handleStoreChange 方法
store.subscribe(this.handleStoreChange);
handleStoreChange(){
this.setState({
data:store.getState()
})
console.log('store chnage',store.getState())
}
如有问题,欢迎留言