redux初探

action是一个普通对象 里面必须有一个type字段,代表将要执行的行为,其他字段自己规划。

action只是描述了将要发生的事情并不能直接修改状态

action创建函数 尽量是一个纯函数,他返回的是action对象

middleware 接受一个next() 的dispatch函数,返回了一个dispatch函数,将返回的dispatch函数作为下一个middleware的next() 一次类推可以达到链式的调用

 它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。 你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。

不管链式调用几次dispatch 最后一次调用dispatch  必须是一个action不能是其他的。来达到数据来源的起点。

import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { createStore ,compose,applyMiddleware} from "redux";
import App from "./components/app";
import reducers from './reducers/index'
import {addTodo} from './actions/index'
const enhancers = compose(
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  );
const store = createStore(reducers,enhancers);
const logger = (store)=>next=>action=>{
  console.log('action',action)
  let result = next(action)
  console.log('state',store.getState())
  return result
}
console.log(logger(store)(store.dispatch)(addTodo('abc')))
//手动实现一个middleware 
function middleware(stroe,middlewares){
  middlewares = middlewares.slice()
  middlewares.reverse()
  let dispatch = store.dispatch
  middlewares.forEach(middleware => {
    dispatch = middleware(stroe)(dispatch)
  })
  return Object.assign({},store,{dispatch})
}
console.log(middleware(store,[logger]))
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

 

 

 

let nextTodoId = 0;

export const addTodo = (text) => {
  return {
    type: "ADD",
    id: nextTodoId++,
    text,
  };
};
export const setVisibilityFilter = (filter) => ({
  type: "SET_VISIBILITY_FILTER",
  filter,
});
export const toggleTodo = (id) => ({
  type: "TOGGLE_TODO",
  id,
});
export const VisibilityFilters = {
  SHOW_ALL: "SHOW_ALL",
  SHOW_COMPLETED: "SHOW_COMPLETED",
  SHOW_ACTIVE: "SHOW_ACTIVE",
};

 reducer函数接收二个参数,一个是旧的状态树,一个是actions对象  返回的是一个新的状态树

可以创建多个子reducer,分别负责状态树中的一部分。最后创建一个根reducers

//子reducers
const todos = (state = [], action) => {
  switch (action.type) {
    case "ADD":
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false,
        },
      ];
      break;
    case "TOGGLE_TODO":
      return state.map((todo) =>
        todo.id == action.id ? { ...todo, completed: !todo.completed } : todo
      );
      break;
    default:
      return state;
      break;
  }
};
export default todos

 

//根reducers
import React from 'react'
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
//自定义根reducers // const todoApp = (state={},action)=>({ // todos:todos(state.todos,action), // visibilityFilter:visibilityFilter(state.abc,action) // }) export default combineReducers({todos,visibilityFilter}) //combineReducers 将reducers 拆分成多个子reducers 并执行

 最后通过createStore 将状态树传递到页面组件树当中

import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { createStore ,compose} from "redux";
import App from "./components/app";
import reducers from './reducers/index'
const enhancers = compose(
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  );
const store = createStore(reducers,enhancers);
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")

)

 将redux应用到组件中时分为容器组件和展示组件,容器组件需要将展示组件连接到store上

//容器组件
import React from 'react'
import { connect } from 'react-redux'
import TodoList from '../components/TodoList'
import {toggleTodo,VisibilityFilters} from '../actions/index'

const getVisibleTodos = (todos,filter)=>{
  switch (filter) {
    case 'SHOW_ALL':
      return todos
      break;
    case 'SHOW_COMPLETED':
      return todos.filter((todo)=>todo.completed)
      break;
    case 'SHOW_ACTIVE':
      return todos.filter(t=>!t.completed)
      break;
    default:
      throw new Error('Unknown filter: ' + filter)
  }
}

const mapStateToProps = (state, ownProps) => {
  console.log(state)
  return {
    todos: getVisibleTodos(state.todos,state.visibilityFilter)
  }
}
const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    toggleTodo: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoList)

 

//展示组件
import React from 'react'
import Todo from './Todo'
const TodoList = ({todos,toggleTodo})=>{
  return (
    <ul>
      {todos.map(todo=>
        <Todo change={()=>toggleTodo(todo.id)} key={todo.id} {...todo} />
        )}
    </ul>
  )
}
export default TodoList

 

posted @ 2020-08-05 17:27  飞奔的龟龟  阅读(101)  评论(0编辑  收藏  举报