[英]How to add the items from a array of JSON objects to an array in Reducer?
So I am fetching the list of 10 todos fromhttps://jsonplaceholder.typicode.com/todos?_limit=10&page=1所以我从https://jsonplaceholder.typicode.com/todos?_limit=10&page=1获取 10 个待办事项列表
I am updating data with the array of these 10 todos.我正在用这 10 个待办事项的数组更新数据。 I have a reducer with action type INITIALUPDATE which I want to set the initialState to the list of todos.
我有一个动作类型为 INITIALUPDATE 的减速器,我想将 initialState 设置为待办事项列表。 So, now initialState is an empty array [], but after the dispatch it should be the same as data.
所以,现在 initialState 是一个空数组 [],但是在 dispatch 之后它应该和 data 一样。
List Notes Screen列出备注屏幕
import { View, Text, FlatList, Button, TouchableOpacity } from "react-native";
import React, { useContext, useState, useEffect } from "react";
import { NotesContext } from "../context/NotesContext";
import { AntDesign } from "@expo/vector-icons";
import { Entypo } from "@expo/vector-icons";
import { Feather } from "@expo/vector-icons";
import axios from "axios";
export default function ListNotes({ navigation }) {
const [data, setData] = useState(null);
const [reloadButton, setReloadButton] = useState(false);
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [hasError, setErrorFlag] = useState(false);
const { state, dispatch } = useContext(NotesContext);
useEffect(() => {
const source = axios.CancelToken.source();
const url = `https://jsonplaceholder.typicode.com/todos?_limit=10&page=1`;
const fetchUsers = async () => {
try {
setIsLoading(true);
const response = await axios.get(url, { cancelToken: source.token });
if (response.status === 200) {
setData(response.data);
setIsLoading(false);
console.log(data);
return;
} else {
throw new Error("Failed to fetch users");
}
} catch (error) {
if (axios.isCancel(error)) {
console.log("Data fetching cancelled");
} else {
setErrorFlag(true);
setIsLoading(false);
}
}
};
fetchUsers();
return () => source.cancel("Data fetching cancelled");
}, [reloadButton]);
return (
<View style={{ flex: 1 }}>
<View style={{ alignItems: "center" }}>
<TouchableOpacity
style={{
marginTop: 5,
backgroundColor: "blue",
width: 60,
height: 60,
borderRadius: 30,
alignItems: "center",
justifyContent: "center",
}}
onPress={() => {
setAddButtonState(addButtonState == true ? false : true);
dispatch({
type: "ADD",
payload: { title: data.title, content: data.body },
});
}}
>
<AntDesign name="pluscircleo" size={24} color="white" />
</TouchableOpacity>
</View>
<FlatList
data={state}
keyExtractor={(item) => item.id}
renderItem={({ item }) => {
return (
<TouchableOpacity
style={{
marginHorizontal: 10,
marginBottom: 5,
backgroundColor: "white",
borderRadius: 5,
height: 35,
elevation: 4,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
onPress={() => {
navigation.navigate("Show", { id: item.id });
}}
>
<View style={{ width: 250 }}>
<Text style={{ fontSize: 24, marginLeft: 10 }}>
{item.title}
</Text>
</View>
<View style={{ flexDirection: "row" }}>
<TouchableOpacity
onPress={() => dispatch({ type: "DELETE", payload: item.id })}
>
<Entypo name="trash" size={30} color="red" />
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate("Update", { id: item.id })}
>
<Feather name="edit" size={30} color="black" />
</TouchableOpacity>
</View>
</TouchableOpacity>
);
}}
/>
</View>
);
}
NotesContext.js NotesContext.js
import React, { createContext, useReducer } from "react";
import { reducer as NotesReducer, initialState } from "../reducer/Notes";
export const NotesContext = createContext();
export const NotesProvider = ({ children }) => {
const [state, dispatch] = useReducer(NotesReducer, initialState);
return (
<NotesContext.Provider value={{ state: state, dispatch: dispatch }}>
{children}
</NotesContext.Provider>
);
};
Notes Reducer笔记减速机
export const initialState = [];
export const reducer = (state, { type, payload }) => {
switch (type) {
case "ADD":
return [
...state,
{
id: Math.random(),
title: payload.title,
content: payload.content,
},
];
case "DELETE":
return state.filter((note) => payload !== note.id);
case "UPDATE":
return state.map((record) => {
if (payload.id == record.id) return payload;
else return record;
});
case "INITIALUPDATE":
return [
...state,
payload.map((item) => {
})
]
}
return state;
};
Looking at case ADD in your reducer, seems like you only want to have id, field, content
fields inside your note.查看减速器中的案例 ADD,似乎您只想在笔记中包含
id, field, content
字段。 But jsonplaceholder data does not contain a content field, so I'm adding some random string for that.但是 jsonplaceholder 数据不包含内容字段,所以我为此添加了一些随机字符串。
Change InitialUpdate case in your reducer like so.像这样更改减速器中的 InitialUpdate 大小写。 Because you're setting the state initially, you don't need to spread the state.
因为您最初设置的是 state,所以不需要传播 state。
case "INITIALUPDATE":
return payload.map(({ id, title }) => ({
id,
title,
content:"Lorem, ipsum dolor sit"
}))
Now inside useEffect
on ListNotesScreen
, after making axios request现在在
useEffect
上的ListNotesScreen
中,发出 axios 请求后
if (response.status === 200) {
// setData(response.data);
dispatch({ type: "INITIALUPDATE", payload: response.data });
setIsLoading(false);
return;
} else {
throw new Error("Failed to fetch users");
}
You should also use the state from context to view updated data.您还应该使用上下文中的 state 来查看更新的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.