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: []
请注意,past
或 future
数组 (stacks) 中的任何元素条目都是数组。
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: []
请注意,past
或 future
数组 (stacks) 中的任何元素条目都是数组。