reactjs 如何在上下文中向数组添加项?(React typescript)

pnwntuvh  于 2023-01-08  发布在  React
关注(0)|答案(2)|浏览(153)

我在我的应用程序中创建了一个上下文搜索,其中有一个名为“searchPosts”的数组。我的目标是在上下文中将一个对象从一个组件发送到这个数组中,从而能够在其他组件中使用它。我希望创建一个存储对象的全局状态
上下文

import { createContext } from "react";

export type SearchContextType = {
    searchPost: (text: string) => void;
};

export const SearchContext = createContext<SearchContextType>(null!);

提供者

import React, { useState } from "react";
import { SearchContext } from "./SearchContext"

export const SearchProvider = ({ children }: { children: JSX.Element }) => {
    const [searchPosts, setSearchPosts] = useState([]);

    const searchPost = (text: string) => {

    }

    return (
        <SearchContext.Provider value={{searchPost}}>
            { children }
        </SearchContext.Provider>
    );
}

我创建了这个搜索函数,因为理论上它应该是一个函数,我可以将项目添加到数组中,但我不知道如何才能做到这一点。
这是我在名为“searchPosts”的组件中的状态,我获取了要传递给全局数组的对象。我希望将信息从该组件中的数组传递给上下文中的全局数组

const navigate = useNavigate();
  const api = useApi();

  const [searchText, setSearchText] = useState('');
  const [searchPost, setSearchPost] = useState([]);

  const handleSearch = async () => {
    const posts = await api.getAllPosts();
    const mapPosts = posts.filter(post => post.title.toLowerCase().includes(searchText));
    setSearchPost(mapPosts);
  }
0pizxfdo

0pizxfdo1#

在组件searchPosts中,尝试使用useContext钩子从上下文组件导入SearchContextsearchPost函数。

import {SearchContext} from './SearchContext'
const {searchPost} = useContext(SearchContext);;

现在,在handleSearch函数中,将mapPosts数组传递给从useContext钩子导入的searchPost函数,如下所示:

const handleSearch = async () => {
    const posts = await api.getAllPosts();
    const mapPosts = posts.filter(post => post.title.toLowerCase().includes(searchText));
    setSearchPost(mapPosts);
    searchPost(mapPosts);
  }

现在,在provider组件中的searchPost函数内添加以下代码:

const searchPost = (posts: any[]) => {
  setSearchPosts(prev => {
     return [...prev, ...posts];
  })
}
r8uurelv

r8uurelv2#

searchPost[]添加到SearchContextType

import { createContext } from "react";

export type SearchContextType = {
  searchPost: (text: string) => void;
  searchResult: string[];
};

export const SearchContext = createContext<SearchContextType>(null!);

创建缩减器以管理调度

//const SEARCH_POST = "SEARCH_POST"; in constants.ts
import { SEARCH_POST } from 'constants';
// reducer
export const reducer = (state, action) => {
  switch (action.type) {
    case SEARCH_POST: {
      return { ...state, searchResult: action.value };
    }
    default: {
      throw new Error(`Unhandled action type: ${action.type}`);
    }
  }
}

创建提供程序

interface InitState {
  searchResult: string[];
}

export const SearchProvider = ({ children }: { children: JSX.Element }) => {
  const initialState: InitState = {
    searchResult: [],
  };

  const [controller, dispatch] = useReducer(reducer, initialState);

  const value = useMemo(() => [controller, dispatch], [controller, dispatch]);

  return <SearchContext.Provider value={value}>{children}</SearchContext.Provider>;
};

export const searchPost = (dispatch, value) => dispatch({ type: SEARCH_POST, value });

现在创建一个定制钩子来访问上下文

export const useSearchState = () => {
  const context = useContext(SearchContext);

  if (!context) {
    throw new Error(
      "useSearchState should be used inside the SearchProvider."
    );
  }

  return context;
};

在您的组件中,可以使用上述方法访问状态。

const [controller, dispatch] = useSearchState();
const {searchResult} = controller;

// to update the post you can call searchPost
// import it from search provider
searchPost(dispatch, posts)

相关问题