简单理解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
})

 
 

代码目录结构
简单理解Redux