簡體   English   中英

在 ReactJS 中的兩個獨立組件之間傳遞數據

[英]Pass data between two independent components in ReactJS

我正在使用 ReactJS 構建一個 Web 應用程序,這需要我實現搜索。 到目前為止,已經使用帶有輸入元素的表單實現了搜索(我為此使用了Fuse.js庫)。 該表單在 NavBar 中實現,在用戶鍵入搜索查詢后,他被重定向到“localhost:3000/search”URL,在那里他可以看到與他的查詢相對應的結果。

這是我在 SearchBar 中用於表單的代碼。

import React, { useState } from 'react';
import { Form, FormControl } from 'react-bootstrap';
import { ReactComponent as SearchLogo } from '../../lib/search-logo.svg';

const SearchBar = () => {
 const [searchQuery, setSearchQuery] = useState({ query: '' });

 const searchQueryHandler = (event) => {
    event.preventDefault();
    setSearchQuery({ query: event.target.value });
 };

 const onFormSubmit = (event) => {
    event.preventDefault();
    window.location.href = "/search";
 }

 return (
    <Form inline className="nav-search-form" onSubmit={onFormSubmit}>
        <SearchLogo className="search-logo" />
        <FormControl
            type="text"
            placeholder="Search spaces of interest"
            className="nav-search"
            value={searchQuery.query}
            onChange={searchQueryHandler} />
    </Form>
 );
}
export default SearchBar;

我需要在另一個 SearchPage 中顯示相應的結果,該 SearchPage 將在提交后從該組件中獲取查詢,然后顯示結果。 這是我為它編寫的代碼。

import React, { useState, useRef } from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import SpaceCardGrid from '../space-card-grid/space-card-grid';
import useSpaces from '../../utils/firebase/hooks/useSpaces';
import moment, { Moment } from 'moment';
import { roundTime } from '../../utils/date';
import Fuse from 'fuse.js';



const SearchPage = (queries) => {
    const [date, setDate] = useState<[Moment, Moment]>([moment(new Date()), moment(new Date())]);
    const [time, setTime] = useState([roundTime(), roundTime(30)]);
    const [dateRangeType, setDateRangeType] = useState<'week' | 'day' | 'now'>('day');
    const spaceCardGridRef = useRef(null);
    const spaces = useSpaces(dateRangeType, date, time, 0);


    const options = {
        shouldSort: true,
        keys: ['title', 'description'],
    };
    const fuse = new Fuse(spaces, options);
    let filteredspaces = spaces;

    if (queries.query !== '') {
        const result = fuse.search(queries.query);
        console.log(result);
        filteredspaces = [];
        result.forEach((space) => {
            filteredspaces.push(space.item);
        });
    }

    return (
        <div>
            <Container fluid className="bottom-container">
                <Row style={{ justifyContent: 'center', alignItems: 'flex-start' }}>
                    <Col>
                        <div className="grid-root">
                            <SpaceCardGrid spaces={filteredspaces} spaceCardGridRef={spaceCardGridRef} />
                        </div>
                    </Col>
                </Row>
            </Container>
        </div>
    );
};

export default SearchPage;

只是為了獲取更多信息, useSpaces()是一個 function,它為我提供了所有數據(並且它這樣做是正確的),並且filteredspaces空間是我希望在屏幕上顯示的最終結果數組。 所有這些事情都完美無缺。

我被困在如何在兩個組件之間傳遞查詢。 我在SearchPage(queries) queries使用的查詢是一個虛擬變量。 我是 React 的新手,我已經了解了 Redux,但是在 2 個組件之間簡單地傳遞一個值似乎需要做很多工作(我可能錯了)。 正如您可以清楚地觀察到的,這些組件不是相關的而是獨立的。 有沒有一種簡單的方法可以做到這一點? 任何幫助將不勝感激!

您可以將useContenxtuseReducer掛鈎用於更簡單的 state 結構。 我在這里創建了一個小例子。 您可以在文檔中找到更多參考

基本上在您的應用程序的根目錄下,您將首先創建一個上下文並將調度和查詢作為值傳遞給您的提供者:

export const QueryDispatch = React.createContext("");
const initialState = { query: "" };

export default function App() {
  const [{ query }, dispatch] = useReducer(queryReducer, initialState);

  return (
    <QueryDispatch.Provider value={{ dispatch, query }}>
      <SearchBar />
      <SearchPage />
    </QueryDispatch.Provider>
  );
}

queryReducer 可能是這樣的:

export default function (state, action) {
  switch (action.type) {
    case 'update':
      return {query: action.query};
    default:
      return state;
  }
}

並且在您可以從您的提供商處使用的任何組件中:

在你的搜索欄

import React, { useContext } from "react";
import { QueryDispatch } from "./App";


const SearchBar = () => {
 const const { dispatch, query } = useContext(QueryDispatch);

 const searchQueryHandler = (event) => {
    dispatch({ type: "update", query: e.target.value })
 };
      ..code

        <FormControl
            type="text"
            placeholder="Search spaces of interest"
            className="nav-search"
            value={query}
            onChange={searchQueryHandler} />

並在您的 SearchPage

import React, { useContext } from "react";
import { QueryDispatch } from "./App";

const SearchPage = () => {
  const { query } = useContext(QueryDispatch);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM