简单理解Redux
之前我一直使用的是dva,说实话,感觉dva比redux更优秀简单(毕竟是redux的改进版)。但是最近有接触的项目要是用redux,在以前看了一下redux,但没太理解就去学习了dva。关于redux的学习文档,感觉初学者看一遍可能会有点懵。我也不太喜欢阅读文字,所以本篇文章大部分都是代码,例子是基于官网的例子,我稍作了一些修改,只要你会react,相信一下就能理解redux。
1.入口文件,和中文文档的一样。
import React from 'react' import { render } from 'react-dom' import { Provider } from 'react-redux' import { createStore } from 'redux' import todoApp from './reducers' import App from './components/App' let store = createStore(todoApp) render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
2.action ,其实action就像一个指令,命令某人做某事,但它需要被派遣(dispatch)
let nextTodoId = 0 export const addTodo = text => { //必需返回一个对象,而且含有type属性 return { type: 'ADD_TODO', id: nextTodoId++, text } } export const setVisibilityFilter = filter => { return { type: 'SET_VISIBILITY_FILTER', filter } } export const toggleTodo = id => { return { type: 'TOGGLE_TODO', id } }
3.reducers,里面会描述真正的做事的过程,每一个reducer的名字就是store(整个应用的state)的一个属性名。
index.js
import { combineReducers } from 'redux' import todos from './todos' import visibilityFilter from './visibilityFilter' const todoApp = combineReducers({ todos, visibilityFilter }) export default todoApp
todos.js
const todos=(state=[],action)=>{ switch(action.type){ case 'ADD_TODO': return [ ...state, { id:action.id, text:action.text, completed:false } ] case 'TOGGLE_TODO': return state.map(todo=> (todo.id===action.id) ?{...todo,completed:!todo.completed} :todo ) default: return state } } export default todos
visibilityFilter.js
const visibilityFilter = (state = 'SHOW_ALL', action) => { switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } export default visibilityFilter
4.components,就是页面的组件,三部分组成
App.js
import Footer from './Footer' import React from 'react' import AddTodo from './AddTodo' import MyTodoList from '../components/MyTodoList' const App = () => ( <div> <AddTodo /> <MyTodoList /> <Footer /> </div> ) export default App
AddTodo.js
import React from 'react' import { connect } from 'react-redux' import { addTodo } from '../actions' class AddTodo extends React.Component { constructor(props){ super(props); this.state={ val:'' } } handleSubmit=()=>{ const {val}=this.state if(val.trim()){ this.props.dispatch(addTodo(val)) this.setState({val:''}) } } handleChange=(e)=>{ this.setState({val:e.target.value}) } render() { const {dispatch}=this.props; const { val } =this.state; return ( <div> <input onChange={this.handleChange} value={val} /> <button onClick={ this.handleSubmit}>add</button> </div> ) } } //经过connect这个HOC包裹的组件,props里面自带dispatch属性 export default connect()(AddTodo)
MyTodoList
import React from 'react' import { connect } from 'react-redux'; import { toggleTodo } from '../actions'; class MyTodoList extends React.Component{ state={ } handleChange=(id)=>{ this.props.dispatch(toggleTodo(id)) } render(){ const {todos}=this.props; return( <ul> {todos.map((todo,index)=>(<li key={index} style={{textDecoration:todo.completed?'line-through':'none'}} onClick={()=>this.handleChange(index)}>{todo.text}</li>))} </ul> ) } } const mapStateToProps=state=>{ console.log(state) //这里进行todo的状态筛选,完成点击按钮显示不同状态的todo的功能 switch(state.visibilityFilter){ case('SHOW_ACTIVE'): return {todos:state.todos.filter(item=>!item.completed)} case('SHOW_COMPLETED'): return {todos:state.todos.filter(item=>item.completed)} default: return {todos:state.todos} } } export default connect(mapStateToProps)(MyTodoList)
Footer.js
import React from 'react' import { setVisibilityFilter } from '../actions' import { connect } from 'react-redux'; class Footer extends React.Component{ state={ activeButton:'all' } handleShowAll=()=>{ this.setState({activeButton:'all'}) this.props.dispatch(setVisibilityFilter('SHOW_ALL')) } handleShowActive=()=>{ this.setState({activeButton:'active'}) this.props.dispatch(setVisibilityFilter('SHOW_ACTIVE')) } handleShowCompleted=()=>{ this.setState({activeButton:'completed'}) this.props.dispatch(setVisibilityFilter('SHOW_COMPLETED')) } render(){ const { activeButton}=this.state; return( <div> <button onClick={this.handleShowAll} style={activeButton==='all'?{background:'red'}:{background:''}}>show all</button> <button onClick={this.handleShowActive} style={activeButton==='active'?{background:'red'}:{background:''}}>show active</button> <button onClick={this.handleShowCompleted} style={activeButton==='completed'?{background:'red'}:{background:''}}>show completed</button> </div> ) } } export default connect()(Footer)
代码里面只用到了mapStateToProps(),它的第一个参数就是整个应用的state,state里面有哪些属性,就看这里
const todoApp = combineReducers({ todos, visibilityFilter })
代码目录结构