繁体   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