如何将 JSON 对象数组中的项目添加到 Reducer 中的数组?

How to add the items from a array of JSON objects to an array in Reducer?

所以我正在从 https://jsonplaceholder.typicode.com/todos?_limit=10&page=1

中获取 10 个待办事项的列表

我正在用这 10 个待办事项的数组更新数据。我有一个动作类型为 INITIALUPDATE 的减速器,我想将 initialState 设置为待办事项列表。所以,现在 initialState 是一个空数组 [],但是在 dispatch 之后它应该和 data.

一样

列出备注屏幕

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

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;
};

查看减速器中的 ADD 大小写,似乎您只想在笔记中包含 id, field, content 字段。但是 jsonplaceholder 数据不包含内容字段,所以我为此添加了一些随机字符串。

像这样更改减速器中的 InitialUpdate 大小写。因为您最初是在设置状态,所以不需要传播状态。

case "INITIALUPDATE":
      return payload.map(({ id, title }) => ({
          id,
          title,
          content:"Lorem, ipsum dolor sit"
        }))
      

现在在 ListNotesScreenuseEffect 内,发出 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");
    }

您还应该使用上下文中的状态来查看更新的数据。