present : past[past.length - 1] ,这应该 return 一个单一的值,但它是 returning 一个完整的数组,就像 slice 方法一样

present : past[past.length - 1] , this should return a single value but it is returning a full array like slice method does


import React, { useState, useRef, useReducer } from "react";
import "./App.css";

function reducer(state,action){ 
  const {past,present,future} = state
  switch(action.type){
    case 'ADD' : return {

      past : [...past,present],
      present : [...present,{id : Math.random(),name : action.payload}],
      future : [],
      canUndo : true,
      canRedo : false,
      
    }

    case "UNDO" : if(!state.canUndo) return state;
    return {
      present :past[past.length - 1], 
      past : past.slice(0,-1),
      future : [present,...future],
      canUndo : past.length > 1,
      canRede : true
    }
    case 'REDO' : return {
    
    }
    default: return state;
  }

}
function App(){
  const input = useRef();

  const initialState = {
    present : [],
    past : [],
    future : [],
    canUndo : false,
    canRedo : false,
  }

  const[items,dispatch] = useReducer(reducer,initialState);

  const addItem = (e) => {
    e.preventDefault();
    dispatch({type : 'ADD', payload : input.current.value})
    input.current.value = '';
 
  }
  return(
    <div>
      <h1>Shopping list</h1>
      <form className='add-product' onSubmit={addItem}>
        <label htmlFOR='product'>product</label>
        <input ref={input} type='text' id='product'/>
        <button type='submit'>Add</button>
      </form>

      <div className='actions'>
        <button onClick={() => dispatch({type : 'UNDO'})}>Undo</button>
        <button onClick={() => dispatch({type : 'REDO'})}>Redo</button>
      </div><ul>
        {items.present.map(item => <li key={item.id}>{item.name}</li>)}
      </ul>

      
    </div>
  )
}



export default App;

大家好,我很难理解这个概念

present : past[past.length - 1]

所以在添加一个值之后,当我点击撤消按钮时,这应该 return 一个单一的值,但它是 return 除了最后一个之外的完整数组,如果有人解释这个概念我将非常感激,为什么它表现得像 slice 方法

如果我理解你的 post,你是在问为什么 past[past.length - 1] returns 数组而不是单个值。

原因是因为它返回单个值,past数组的最后一个元素,而这个值恰好也是一个数组。换句话说,您的状态,即 present 是一个值数组,您正在维护“撤消”和“重做”堆栈。当一个新项目被添加到 present 数组时,先前的 present 数组被添加 (PUSHED) 到 past 撤消堆栈。撤消此操作时,您将从 past 撤消堆栈中删除最后一项 (POPPED) 并替换当前的 present 数组。

示例:

初始状态:

past: []
present: []
future: []

ADD 1: 现在被推到过去 ([].push([]) -> [[]]), 1 被推到现在 ([].push(1) -> [1])

past: [[]]
present: [1]
future: []

ADD 2: 现在被推到过去 ([[]].push([1]) -> [[], [1]]), 2 被推到现在 ([1].push(2) -> [1, 2])

past: [[], [1]]
present: [1, 2]
future: []

撤消:现在被推入未来 ([].push([1, 2]) -> [[1, 2]]),过去被弹出 ([[], [1]].pop() -> [[]]) 并设置为现在 ([1])

past: [[]]
present: [1]
future: [[1, 2]]

ADD 3:现在被推到过去([[]].push([1]) -> [[], [1]]),3被推到现在([1].push(3) -> [1, 3]),未来被清除([]

past: [[], [1]]
present: [1, 3]
future: []

ADD 4: 现在被推到过去 ([[], [1]].push([1, 3]) -> [[], [1], [1, 3]]), 4 被推到现在 ([1, 3].push(4) -> [1, 3, 4])

past: [[], [1], [1, 3]]
present: [1, 3, 4]
future: []

请注意,pastfuture 数组 (stacks) 中的任何元素条目都是数组。