#16 实现 Users Reducer


  • 0

    case 'DELETE_USER':
          let newState = [...state]
          newState.splice(action.index, 1)
          return newState
    

  • 1

    其实关键就是理解reducer是纯函数的概念,接收state和action,然后不产生副作用(比如不要修改state的内容),入参决定唯一确定的出参。

    const usersReducer = (state, action) => {
        if (!state)
          return []
        switch (action.type) {
          case 'ADD_USER': {
            return [...state, action.user]
          }
          case 'DELETE_USER': {
            return [...state.slice(0, action.index), ...state.slice(action.index+1)]
          }
          case 'UPDATE_USER': {
            let newUser = {...state[action.index], ...action.user}
            return [...state.slice(0, action.index), newUser, ...state.slice(action.index+1)]
          }
          default: return state
        }
    }
    

  • 0

    @wangxf case 'DELETE_USER':
    return state.filter((item,index)=>index!==action.index)更简单


  • 0

    const usersReducer = (state, action) => {
      if (!state) return [];
      switch(action.type) {
        case 'ADD_USER':
          state = state.concat(action.user);
          return state;
        case 'DELETE_USER':
          state = state.concat();
          state.splice(action.index, 1);
          return state;
        case 'UPDATE_USER':
          state = state.map((t, index) => {
            if (index === action.index) {
              return {
                ...t,
                ...action.user,
              };
            }
            return t;
          })
          return state;
        default:
          return state;
      }
    }

  • 0

    首先抓住关键:
    reducer纯函数特性决定它只能用于初始化或计算新的state,但绝对不能去修改state

    ES6比较好的办法:

    const usersReducer = (state, action) => {
      if (!state) return []
      switch (action.type) {
        case "ADD_USER":
          return [...state, action.user]
        case "DELETE_USER":
          return [...state.slice(0, action.index), ...state.slice(action.index + 1)]
        case "UPDATE_USER":
          let user = {
            ...state[action.index],
            ...action.user,
          }
          return [
            ...state.slice(0, action.index),
            user,
            ...state.slice(action.index + 1),
          ]
        default:
          return state
      }
    }
    

    土办法:

    const usersReducer = (state, action) => {
      if (!state) return []
      switch (action.type) {
        case "ADD_USER":
          return [...state, action.user]
        case "DELETE_USER":
          return state.slice(0, action.index).concat(state.slice(action.index + 1))
        case "UPDATE_USER":
          let user = {
            ...state[action.index],
            ...action.user,
          }
          return state
            .slice(0, action.index)
            .concat(user, state.slice(action.index + 1))
        default:
          return state
      }
    }
    

  • 0

    0_1541593832474_upload-887f1773-4fe3-40e9-97b3-77cb47f5c921


  • 0

    @ScriptOJ
    type Type<T extends String> = {type:T}

    interface User{
    name:string,
    age:number
    gender: 'female' | 'male'
    }

    type UPDATE_USER = {index:number} & Partial<User> & Type<'UPDATE_USER'>

    type DELETE_USER = {index:number} & Type<'DELETE_USER'>

    type ADD_USER = User & Type<'ADD_USER'>

    type UserAction = DELETE_USER | UPDATE_USER | ADD_USER;

    function userReducer(state:User[]=[],action:UserAction){
    switch(action.type){
    case 'ADD_USER':
    return [...state,action]
    case 'DELETE_USER':
    return [...state.filter((user,index)=>index != action.index)]
    case 'UPDATE_USER':
    return [...state.map((user,index)=>{
    if(index == action.index){
    delete action.index
    return {...user,...action}
    }
    return user
    })];
    default:
    return state
    }
    }

    function createStore<S,T extends string,A extends Type<T>>(reducer:(state:S,action:A)=>S) {
    let state:S
    const listeners:Array<()=>void> = []
    const subscribe = (listener:()=>void) => listeners.push(listener)
    const getState = () => state
    const dispatch = (action:A) => {
    state = reducer(state, action!)
    listeners.forEach((listener) => listener())
    }
    return { getState, dispatch, subscribe }
    }

    let stroe = createStore(userReducer)

    /* 修改用户操作 */
    stroe.dispatch({
    type: 'UPDATE_USER',
    index: 5,
    })

    stroe.dispatch({
    type:'ADD_USER',
    name: '张三',
    age: 20,
    gender: 'male'
    })

    stroe.dispatch({
    type:'DELETE_USER',
    index:1
    })


  • 0

    const usersReducer = (state, action) =>{
      if(!state) {
        return []
      }
      const newState = [...state]
      switch(action.type) {
        case 'ADD_USER': 
          newState.push(action.user)
          return newState
        case 'DELETE_USER':
          newState.splice(action.index, 1)
          return newState
        case 'UPDATE_USER':
          return [...newState.map((user, index) => (
            index === action.index ? {...user, ...action.user} : user 
          ))]
        default: return state
      }
    }
    

  • 0

    const usersReducer = (state, action) => {
      if (!state) return [];
      switch(action.type) {
        case 'ADD_USER':
          return [...state, action.user];
        case 'DELETE_USER':
          var newState = [...state];
          newState.splice(action.index, 1);
          return newState;
        case 'UPDATE_USER':
          var newState = [...state];
          newState[action.index] = {...newState[action.index], ...action.user}
        //下面的代码也OK  newState[action.index] = Object.assign({}, newState[action.index], action.user)
          return newState;
        default:
          return state;
      }
    }

  • 0

    const usersReducer = (state = [], action) => {
      if (state.length === 0) return state;
      const { type, index, user } = action;
      
      switch(type) {
        case 'ADD_USER':
          return [...state, user];
        case 'DELETE_USER':
          return [...state.slice(0, index), ...state.slice(index + 1)];
        case 'UPDATE_USER':
          return [...state.map((user, i) => {
            return i === index ? { ...user, ...action.user} : user
          })]
        default:
          return state;
      }
    }
    

  • 0

    const usersReducer = (state = [],action) => {
      switch(action.type) {
        case 'ADD_USER': {
          return [...state,action.user]
        }
        case 'DELETE_USER': {
          return state.filter((item,index)=> action.index !== index)
        }
        case 'UPDATE_USER': {
          return state.map((item,index)=> {
            if(action.index === index){
              return {
                ...item,
                ...action.user
              }
            }
            return item
          })
        }
        default:
          return state
      }
    }
    

  • 0

    const usersReducer = (state, action)=>{
      if (!state){
        return []
      }
      const index = action.index, user = action.user;
      switch(action.type){
        case 'ADD_USER': 
          return [...state, user];
        case 'DELETE_USER': 
          return [...state.slice(0, index), ...state.slice(index+1)];
        case 'UPDATE_USER':
          return [...state.slice(0, index),  {...state[index], ...user}, ...state.slice(index+1)];
        default:
          return state;
      }
    }

  • 0

    @ScriptOJ 更新部分为啥报错啊

    const usersReducer = function (state,action) {
    if(!state) {
    return []
    }
    switch (action.type) {
    case 'ADD_USER':{
    var b= [...state]
    b.push(action.user)
    return b
    }

      case 'DELETE_USER':{
        switch (action.index) {
          case action.index:{
             var b = [...state];
             b.splice(action.index,1);
             return b
          }
        }
      }
      case 'UPDATE_USER':{
        switch (action.index){
          case action.index:{
             var b = [...state];
             if (action.user.username){
                b[action.index].username = action.user.username
             }
             
             if (action.user.age){
                b[action.index].age = action.user.age
             }
             
             if (action.user.gender){
                b[action.index].gender = action.user.gender
             }
            
             return b
          }
        }
      }
      default:
        return state
    

    }


登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待