在使用Android Studio设置的React Native应用程序中,我使用redux-persist保持状态,存储引擎为AsyncStorage。在应用程序中,我有一个“添加”按钮和一个“删除”按钮,用于从状态中添加和删除项目。
“添加”按钮可以正常工作,它将状态添加到项目,然后重新渲染屏幕。 但是,“删除”按钮虽然从状态中删除了一个项目(我已经在React Native Debugger上看到了它),但它不会重新渲染屏幕并保持状态。但是代码的另一个版本可以工作。
我想知道为什么以前的版本不起作用。这是我的减速器功能:
//reducer.js
import React from 'react';
const initialState = {
key: [
{ id: 0 },
{ id: 1 }
]
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'SAVE':
return { key: [...state.key, action.payload] };
// this version doesn't re-render the screen and doesn't persist
case 'REMOVE':
let { key } = state;
key.pop();
return { key };
// this version re-renders the screen and persists
case 'REMOVE':
let { key } = state;
return { key : key.slice(0, key.length - 1)};
default:
return state;
}
};
export { reducer };
以下是我的 store.js , main.js , App.js 和依赖项:
// store.js
import React from 'react';
import { createStore } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-community/async-storage';
import { reducer } from './reducer';
const persistConfig = {
key: 'abc',
storage: AsyncStorage
};
const pReducer = persistReducer(persistConfig, reducer);
let store = createStore(
pReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
let persistor = persistStore(store);
export { store, persistor };
// main.js
import React, { useState } from 'react';
import { ScrollView, View, Text, Button } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';
const Main = () => {
let key = useSelector(state => state.key);
const dispatch = useDispatch();
const [show, setShow] = useState(false);
const add = () => {
dispatch({ type: "SAVE", payload: { id: key.length } });
}
const remove = () => {
dispatch({ type: "REMOVE" });
}
const load = () => {
setShow(true);
}
const items = key.map((item) => <Text key={item.id}>{item.id}</Text>);
return (
<ScrollView>
<View>
<Button
title='add'
onPress={add}
/>
<Button
title='remove'
onPress={remove}
/>
<Button
title='load'
onPress={load}
/>
{show ? <Text>your state contains {key.length} items</Text> : <Text></Text>}
</View>
<View>
{items}
</View>
</ScrollView>
);
};
export default Main;
// App.js
import React from 'react';
import { Provider } from 'react-redux';
import { store, persistor } from './store';
import { PersistGate } from 'redux-persist/integration/react';
import Main from './main';
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<Main/>
</PersistGate>
</Provider>
);
};
export default App;
//package.json
"dependencies": {
"@react-native-community/async-storage": "^1.12.0",
"@react-native-community/masked-view": "^0.1.10",
"@react-navigation/native": "^5.7.3",
"@react-navigation/stack": "^5.9.0",
"react": "16.13.1",
"react-native": "0.63.2",
"react-native-gesture-handler": "^1.8.0",
"react-native-reanimated": "^1.13.0",
"react-native-safe-area-context": "^3.1.8",
"react-native-screens": "^2.11.0",
"react-redux": "^7.2.1",
"redux": "^4.0.5",
"redux-persist": "^6.0.0"
},
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/runtime": "^7.8.4",
"@react-native-community/eslint-config": "^1.1.0",
"babel-jest": "^25.1.0",
"eslint": "^6.5.1",
"jest": "^25.1.0",
"metro-react-native-babel-preset": "^0.59.0",
"react-test-renderer": "16.13.1"
}
答案 0 :(得分:4)
您需要克隆该数组,然后对其进行修改,然后尝试对原始数组进行突变。
slice()方法将数组的一部分的浅表副本返回到从头到尾(不包括end)选择的新数组对象中,其中start和end表示该数组中项的索引。原始数组将不会被修改。
pop方法从数组中删除最后一个元素,并将该值返回给调用方。
因此,基本上,这就是.slice()
有效而.pop()
在这种情况下无效的原因。
答案 1 :(得分:1)
前者不起作用,因为您正在对数组进行变异。
请考虑以下片段:
const bla = {
key: [1, 2]
};
let {
key
} = bla;
key.pop();
console.log(key);
console.log(bla);
const bla = {
key: [1, 2]
};
let {
key
} = bla;
console.log(key.slice(0, key.length - 1));
console.log(bla)
请注意,console.log(bla)
会在pop
修改数组时记录不同的值,而slice
会创建一个新数组。