javascript - 默认情况下返回变异状态
问题描述
我正在使用 ethplorer 的 API 和前端的 React、redux-react 和 thunk 中间件构建一个 ETH 投资组合跟踪器。存储的主要组件是一个对象数组(令牌)。您可以在下面看到它的减速器和操作:
import {createToken, initializeTokens, deleteToken, replaceTokens} from '../services/tokens'
const tokenReducer = (state = [], action) => {
switch (action.type) {
case 'ADD_TOKEN':
return state.concat(action.data)
case 'ERASE_TOKEN':
return state.filter(token => token.address !== action.data)
case 'INIT_TOKENS':
return action.data
default:
return state
}
}
//Defining Actions
export const addToken = address => {
return async dispatch => {
const newToken = await createToken(address)
dispatch({
type: 'ADD_TOKEN',
data: newToken
})
}
}
export const updateTokens = () => {
return async dispatch => {
const updatedTokens = await initializeTokens()
await replaceTokens(updatedTokens)
dispatch({
type: 'INIT_TOKENS',
data: updatedTokens
})
}
}
export const eraseToken = address => {
return async dispatch => {
await deleteToken(address)
dispatch({
type: 'ERASE_TOKEN',
data: address
})
}
}
export default tokenReducer
导入的函数用于从 API 获取令牌,然后将它们保存到本地数据库中。操作的另一个组件是 MarketCap 过滤器(字符串),我使用它来根据市值(从大到小、从小到大或无)对代币进行排序。它有一个超级简单的减速器和一个动作:
const mcReducer = (state='NONE', action) => {
switch (action.type) {
case 'SET_MC_FILTER':
return action.filter
default:
return state
}
}
export const mcFilterChange = filter => {
return {
type: 'SET_MC_FILTER',
filter
}
}
export default mcReducer
当我开始对标记进行排序以在 React 组件中显示时,问题就开始了。虽然我不打算更改令牌状态,而只想更改显示的令牌数组,但在我按 MC 排序后,我的令牌状态始终会更改为已排序的状态。所以发生的事情是:programm 调度 SET_MC_FILTER => TokenList 根据过滤器对令牌进行排序 => tokenReducer 返回变异状态而不是旧状态。我不明白为什么会发生这种情况,因为我没有调度任何应该影响令牌状态的操作,并且默认情况下 tokenReducer 应该只返回存储在其中的状态。这是问题显然发生的最后一段代码:
const initTokens = useSelector(state => state.tokens)
const mcFilter = useSelector(state => state.mcFilter)
const getDisplayTokens = inTokens => {
switch (mcFilter) {
case 'NONE':
return inTokens
case 'DESCENDING':
return inTokens.sort(compareMCDescending)
case 'ASCENDING':
return inTokens.sort(compareMCAscending)
default:
return inTokens
}}
return(
<div className='token-list'>
{getDisplayTokens(initTokens).map(t =>
<TokenTile token={t} key={t.id}/>
)}
</div>
)
我试图用 redux-devtools 的 debugger 和 trace 选项来追踪令牌更改的确切位置,但是 tokenReducer 在任何地方都会立即返回更改的状态,我不知道为什么。任何帮助将不胜感激
解决方案
Array.prototype.sort()
就地改变数组。你永远不应该尝试.sort()
直接调用从 Redux 状态读取的数组。您必须制作数组的副本,然后对它们进行排序。
另外,请注意,您应该使用我们的官方 Redux Toolkit 包,它既可以消除 reducer 中的突变,也可以在您尝试在reducer之外修改代码时抛出错误。
有关如何正确使用 RTK 的教程,请参阅https://redux.js.org/tutorials/fundamentals/part-8-modern-redux 。
推荐阅读
- python - 在熊猫中导出 csv 时显示错误的标签
- python - 我们可以从字符串中提取数字并将它们相乘吗
- vue.js - 设置新的 Vuetfy 2 Beta 7 - 观察者“isDark”的吸气剂错误
- swift - 使用 url-schema 打开应用程序,但如果 url 有一些对象,请不要打开应用程序,只需在浏览器中打开
- javascript - 在 javascript 中终止挂起的 Promise
- video - stereo_mode=left_right 元数据标签消失
- java - 返回单声道
使用反应式 MongoDB 模板 - kubernetes - 为什么 kubernetes HPA 没有缩小 pod?
- android - 是否可以从 Android 应用程序执行 Shell 脚本
- javascript - jQuery:一旦条件语句返回错误,停止窗口高度重新计算