redux以及相关
程序员文章站
2024-03-06 10:32:13
...
react
只是轻量级的视图层框架,大型的应用应该拥有数据层框架配合使用。目前最好的应该是redux
,是一种很好解决 组件传递数据的一种规范。
什么是redux flux
也是facebook
跟 react
一起发布的数据管理工具,但是后期使用中发现不能完美的解决数据统一的管理的理念,因此又引入了reducer
的概念,形成了现在的redux
,因此可以说:
redux = reducer + flux
一:redux
的基本使用方法
- 创建
store
仓库,使用createStore
进行创建,就类似于创建了图书馆,但是当你借书的时候管理员不知道你要借那一本书,需要检索书的数据库,reducer
就是这个数据库,只有利用这个书的数据库才能完整的创建一个图书馆。
// index.js
import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(
reducer,
// 浏览器端 redux-extension-devtool插件的检测配置
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store
- 然后创建
reducer.js
,也就是图书馆数据库,创建初始化的数据,返回的是一个函数,action
是组件传递的动作
import {CHANGE_INPUT_VALUE} from './actionTypes'
// 默认的数据
const defaultDate = {
nowInputValue:'',
list:[]
}
export default (state = defaultDate,action)=>{
if(action.type === CHANGE_INPUT_VALUE){
// 深拷贝一份初始化数据,不能修改state,注意区别Object.assen()
const newState = JSON.parse( JSON.stringify(state) )
newState.nowInputValue = action.value
return newState
}
// 必须要返回一个值,默认返回state
return state
}
其中actionType.js
是一份常量的配置表,为什么这么写? 常量变量错误会报出异常,字符串写错是不会报出异常,方便调试
export const CHANGE_INPUT_VALUE = 'chane_input_value'
创建完上面,开始在组件里面使用
import store from './store'
import {CHANGE_INPUT_VALUE} from './store/store/actionTypes'
class TodoAntd extends Component{
constructor(props){
super(props)
// store 提供的方法,获取store里面的数据,初始化页面数据
this.state = store.getState()
// 广播函数,监听store里面state的变化,只要一发生就会自动执行里面的函数,可以实现ui的变化
store.subscribe(this.addEventInput)
}
addEventInput = ()=>{
// 使用store里面state改变该组件里面state数据,ui就会跟着发生变化
this.setState( store.getState() )
}
handleInput = (e)=>{
const action = {
type:CHANGE_INPUT_VALUE,
value:e.target.value
}
store.dispatch(action)
}
改进1:在复杂的组件里面使用这样子创建action
特别散,不方便统一管理,因此我们使用统一的对象进行创建action,新建一个actionCreator.js
的文件。
import {CHANGE_INPUT_VALUE} from './actionTypes'
// 返回的是一个函数,里面自动返回一个对象
export const getHandleInput_action = (value) =>({
type:CHANGE_INPUT_VALUE,
value
})
因此,最后修改组件里面的写法如下:
import store from './store'
import {CHANGE_INPUT_VALUE} from './store/actionTypes'
import {getHandleInput_action} from './store/actionCreator'
class TodoAntd extends Component{
constructor(props){
super(props)
this.state = store.getState()
store.subscribe(this.addEventInput)
}
addEventInput = ()=>{
this.setState( store.getState() )
}
handleInput = (e)=>{
// 变化的地方,利用函数进行action的创建
const action = getHandleInput_action(e.target.value)
store.dispatch(action)
}
总结1:
1:store
是惟一的
2:只有store
才能改变自己的内容,而不是reducer,注意一下,reducer
必须是纯函数,就是给定固定的输入,输出的结果就是固定的,不能有其他的副作用
二: UI
组件,容器组件,无状态组件。 ui
组件负责渲染,是一个傻瓜组件,容器组件负责逻辑,传值给ui
组件,是聪明组件,在一般的react
开发中更加高效简洁。
// 相关片段 容器组件处理完逻辑以后都传递给ui组件
render(){
return(
<TODO_UI
nowInputValue = {this.state.nowInputValue}
handleInput = { this.handleInput }
keyPressfn = { this.keyPressfn }
list = { this.state.list }
deleteFn = { this.deleteFn }
/>
)
}
// ui 组件 接受参数
export default class TODO_UI extends Component{
render(){
return(
<div>
<Input
value={this.props.nowInputValue}
onChange={this.props.handleInput}
onKeyDown={this.props.keyPressfn}
/>
<List
bordered
dataSource={this.props.list}
renderItem={ (item,index) => (<List.Item onClick={ ()=>{ this.props.deleteFn(index) } } >{item}</List.Item>) }
/>
</div>
)
}
}
无状态组件
:当组件只有一个render
的函数,就是一个无状态组件,其实就是一个函数,接受一个参数props
,返回的是jsx
片段
远比普通组件的性能高很多,就是一个普通的函数,因此使用无状态组件定义一个组件性能更加优、
import React,{Fragment } from 'react'
const TODO_UI = (props) => {
return(
<Fragment>
<Input
placeholder="今天的计划1"
value={props.nowInputValue}
onChange={props.handleInput}
onKeyDown={props.keyPressfn}
/>
<List
bordered
dataSource={props.list}
renderItem={ (item,index) => (<List.Item onClick={ ()=>{ props.deleteFn(index) } } >{item}</List.Item>) }
/>
</Fragment>
)
}
export default TODO_UI