【问题标题】:present : past[past.length - 1] , this should return a single value but it is returning a full array like slice method doespresent : past[past.length - 1] ,这应该返回一个值,但它返回一个完整的数组,就像 slice 方法一样
【发布时间】:2021-09-10 20:36:43
【问题描述】:

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;

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

现在:过去[past.length - 1]

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

【问题讨论】:

  • 我认为问题出在您的一些操作中,您正在像这样连接数组:[...past,present] -> 在这里,不应该是[...past,...present]。此外,这个 future : [present,...future] 应该是:future : [...present,...future]。对?我可能是错的,但对我来说就是这样......
  • codesandbox 中运行您的代码似乎运行正常(据我所知)。问题是什么?你是在问为什么past[past.length - 1] 返回一个数组?

标签: javascript reactjs use-reducer


【解决方案1】:

如果我理解您的帖子,您会问为什么 past[past.length - 1] 返回一个数组而不是单个值。

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

例子:

初始状态:

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

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

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

添加 2:现在被推到过去 ([[]].push([1]) -&gt; [[], [1]]),2 被推到现在 ([1].push(2) -&gt; [1, 2])

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

UNDO:现在被推入未来 ([].push([1, 2]) -&gt; [[1, 2]]),过去被弹出 ([[], [1]].pop() -&gt; [[]]) 并设置为现在 ([1])

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

添加 3:现在被推到过去 ([[]].push([1]) -&gt; [[], [1]]),3 被推到现在 ([1].push(3) -&gt; [1, 3]),未来被清除 ([])

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

添加 4:现在被推到过去 ([[], [1]].push([1, 3]) -&gt; [[], [1], [1, 3]]),4 被推到现在 ([1, 3].push(4) -&gt; [1, 3, 4])

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

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

【讨论】:

  • 哇,非常感谢你解释得这么深,对不起我的英语不好我再次有一个问题,假设我什么时候会使用这个present :past[past.length - 1] ...不会改变原来的礼物状态为只有 1 个值我的意思是假设现在有 3 个项目 [ {1}, {2}, {3}] 现在如果我使用 present :past[past.length - 1],它只会返回一个像 [ {} ] 我们正在撤消的单一数组1 个值,即最后一个 {3}。在当前数组中,但通过这样做present :past[past.length - 1],它将用单个数组替换当前
  • 请阅读本文,我已尝试解释我的第二个问题stackoverflow.com/questions/69142118/…
  • @AdanAli 您的其他问题似乎与此问题重复。 present 总是 只是一个值,即当前值,而 pastfuture总是 是一个数组(本质上是一个“堆栈”)的“当前”值。撤消时您所做的只是将当前当前值移动到future 堆栈的顶部,并将past 堆栈的顶部移动到当前值,而当您重做时则相反。
  • 目前有多个项目,无论我点击add ..items 都存储在present 中,这就是我使用item.present.map(item =&gt; &lt;li&gt;{item}&lt;/li&gt; 在浏览器上显示链接项目的原因
猜你喜欢
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 2018-10-02
  • 1970-01-01
相关资源
最近更新 更多