React Native AsyncStorage Error: TypeError - undefined is not a function (near "...state.reduce...")
P粉734486718
2023-08-29 16:54:51
<p>I'm using AsyncStorage to try to persist my redux state in my React app, but I'm getting this error: <code>TypeError: undefined is not a function (near '...state.reduce. ..')</code>.
I looked at other answers with similar errors but no success. I'm not even sure which one is undefined since it just says "near".我已经检查了state对象,它不是空的。
这是我的主要代码:
应用程序.js:</p>
<pre class="brush:php;toolbar:false;">import Main from "./src/components/Main"
import { NativeRouter } from "react-router-native"
import { createStore } from "redux"
import { Provider } from "react-redux"
import reducer from "./src/reducer"
import AsyncStorage from "@react-native-async-storage/async-storage"
import { persistStore, persistReducer } from "redux-persist"
import { PersistGate } from "redux-persist/integration/react"
import Text from "./src/components/Text"
const persistConfig = {
key: "root",
storage: AsyncStorage,
}
const persistedReducer = persistReducer(persistConfig, reducer)
const store = createStore(persistedReducer)
const persistor = persistStore(store)
export default function App() {
return (
<NativeRouter>
<Provider store={store}>
<PersistGate loading={<Text>Loading...</Text>} persistor={persistor}>
<Main />
</PersistGate>
</Provider>
</NativeRouter>
)
}</pre>
<p>这是reducer的代码:
减速器.js:</p>
<pre class="brush:php;toolbar:false;">const reducer = (state = [], action) => {
switch (action.type) {
case "NEW_NOTE": {
console.log("state :>> ", state)
const max = state.reduce(
(prev, current) => {
// if (!current) return prev
return current.id > prev.id ? current : prev
},
{ id: 0, body: "" }
)
const newNote = { id: max.id 1, body: "" }
return state.concat(newNote)
}
case "UPDATE_NOTE": {
const newNotes = state.filter((note) => action.data.id !== note.id)
return [action.data, ...newNotes]
}
case "DELETE_NOTE": {
return state.filter((note) => action.id !== note.id)
}
default: {
return state
}
}
}
export default reducer</pre>
<h1>编辑</h1>
<p>持久化的reducer将数组更改为对象。我想我需要改变我的代码以适应这个。Any ideas on why this is happening? </p>
<p>Use the state object of the ordinary reducer: </p>
<pre class="brush:php;toolbar:false;">[{"body": "Ddtstostksoyoyyxcuj", "id": 2}, {"body": "Ftistldpufipf
Hhxgjbv", "id": 1}]</pre>
<p>Use the state object of the persistent reducer: </p>
<pre class="brush:php;toolbar:false;">{"0": {"body": "my first note", "id": 1}, "1": { "body": "my second note", "id": 2}, "2": {"body": "my third note", "id": 3}}</pre> ;
<h1>Repair</h1>
<p>reducer.js</p>
<pre class="brush:php;toolbar:false;">const reducer = (state = [], action) => {
state = Object.values(state)
...</pre>
<p>Selector: </p>
<pre class="brush:php;toolbar:false;">const notes = useSelector((state) => Object.values(state).slice(0, -1))</pre>
<p>I have to delete the -1th element because the persistor contains an extra attribute:
<code>{"0": {"body": "Hi", "id": 7}, "1": {"body": "", "id": 8}, "2": {" body": "", "id": 9}, "_persist": {"rehydrate": true, "version": -1}}</code></p>
Why does a TypeError occur?
You encountered this error
TypeError: undefined is not a function (near '...state.reduce...')
, becausestate
is not an array, but an objectObject has no
reduce
methodWhy
react-persist
converts your array to an object?In the
line
of the react-persist source code, you can seelet { _persist, ...rest } = state || {}
. Unfolding an array like this causes it to be converted into an object.Is this a bug?
Probably yes, I can't find any information in the documentation that the state must be an object.
How to fix it?
Either wrap your state in an object instead of using an array directly
Either convert the object back to an array each time it is used