[英]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 个组件之间简单地传递一个值似乎需要做很多工作(我可能错了)。 正如您可以清楚地观察到的,这些组件不是相关的而是独立的。 有没有一种简单的方法可以做到这一点? 任何帮助将不胜感激!
您可以将useContenxt
和useReducer
挂钩用于更简单的 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.