Javascript 在ReactJS中的两个独立组件之间传递数据
我正在用ReactJS构建一个web应用程序,这需要我实现一个搜索。到目前为止,搜索已经通过一个带有输入元素的表单实现(我正在为此使用库)。表单在导航栏中实现,用户键入搜索查询后,他将被重定向到“localhost:3000/search”URL,在那里他可以看到与其查询对应的结果 这是我在搜索栏中用于表单的代码Javascript 在ReactJS中的两个独立组件之间传递数据,javascript,reactjs,components,Javascript,Reactjs,Components,我正在用ReactJS构建一个web应用程序,这需要我实现一个搜索。到目前为止,搜索已经通过一个带有输入元素的表单实现(我正在为此使用库)。表单在导航栏中实现,用户键入搜索查询后,他将被重定向到“localhost:3000/search”URL,在那里他可以看到与其查询对应的结果 这是我在搜索栏中用于表单的代码 import React, { useState } from 'react'; import { Form, FormControl } from 'react-bootstrap'
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;
import React,{useState}来自“React”;
从“react bootstrap”导入{Form,FormControl};
从“../../lib/search logo.svg”导入{ReactComponent as SearchLogo};
常量搜索栏=()=>{
const[searchQuery,setSearchQuery]=useState({query:'});
const searchQueryHandler=(事件)=>{
event.preventDefault();
setSearchQuery({query:event.target.value});
};
const onFormSubmit=(事件)=>{
event.preventDefault();
window.location.href=“/search”;
}
返回(
);
}
导出默认搜索栏;
我需要在另一个搜索页面中显示相应的结果,该页面将在提交后从此组件获取查询,然后显示结果。这是我为它编写的代码
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;
import React,{useState,useRef}来自“React”;
从“react bootstrap”导入{Col,Container,Row};
从“../space card grid/space card grid”导入SpaceCardGrid;
从“../../utils/firebase/hooks/usespace”导入usespace;
导入力矩,{moment}来自'moment';
从“../../utils/date”导入{roundTime};
从“Fuse.js”导入Fuse;
const SearchPage=(查询)=>{
const[date,setDate]=useState([moment(new date()),moment(new date()))];
const[time,setTime]=useState([roundTime(),roundTime(30)];
const[dateRangeType,setDateRangeType]=useState('day');
const spaceCardGridRef=useRef(null);
常量空间=使用空间(dateRangeType、日期、时间,0);
常量选项={
应该排序:是的,
关键字:[“标题”、“说明”],
};
常量保险丝=新保险丝(空格、选项);
让filteredspaces=spaces;
如果(querys.query!=''){
const result=fuse.search(querys.query);
控制台日志(结果);
filteredspaces=[];
result.forEach((空格)=>{
filteredspaces.push(space.item);
});
}
返回(
);
};
导出默认搜索页面;
仅提供附加信息usespace()
是一个函数,它为我提供了所有数据(而且它的操作正确),而filteredspaces
是我希望在屏幕上显示的最终结果数组。所有这些东西都运转良好
不过,我一直在研究如何在这两个组件之间传递查询。我在
SearchPage(querys)
中使用的querys
是一个伪变量。我是一个新的反应者,并且我已经了解了Redux,但是简单地在两个组件之间传递一个值似乎需要做很多工作(我可能错了)。正如您可以清楚地观察到的,这些组件并不相关,而是独立的。有没有一个简单的方法可以做到这一点?任何帮助都将不胜感激 您可以使用useContenxt
和useReducer
挂钩来实现更简单的状态结构。我创建了一个小例子。您可以在以下网址找到更多参考资料:
基本上,从应用程序的根目录开始,您将创建一个上下文,并将分派和查询作为值传递给提供商:
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>
);
}
在您可以从供应商处使用的任何组件上:
在搜索栏上
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} />
谢谢你的这种方法。但是,我在代码中使用了typescript,它在app.tsx文件中显示了如下语法错误:
类型“{dispatch:React.dispatch;querys:any;}”不能分配给类型“string”。
您能帮我吗?据我所知,这是因为我们将初始状态指定为constquerydispatch=React.createContext(“”)好的,我明白了。从网上提供的几个答案中,我意识到这是一个typescript问题,我通过定义一个与所需数据类型对应的接口来解决它。是的!!现在一切都很好。正在两个组件之间发送数据。不过我还有一个问题。刷新页面时,查询值是否会被清除?有没有可能存储它,这样我们就可以让你知道它在那里,即使页面刷新!对于刷新时的数据持久性,可以使用localStorage
或sessionStorage
。大多数情况下,您会使用constinitialstate=JSON.parse(localStorage.getItem('query'))|{query:}
。在某个时刻,您将在localStorage上保持redux状态,比如localStorage.setItem('query',JSON.stringify({query}))
。在您的情况下,您可能只对表单提交感兴趣。您可能有兴趣更频繁地设置localState。只需记住在设置之前进行字符串化,在检索之前进行解析。明白了。非常感谢!
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} />
import React, { useContext } from "react";
import { QueryDispatch } from "./App";
const SearchPage = () => {
const { query } = useContext(QueryDispatch);