如何导航到另一个组件并传递数据
How to navigate to another component and pass data
我目前正在尝试完成从组件到组件的路由并传递数据,以便新打开的组件可以使用它。经过几个小时的研究,我偶然发现了一些对我的情况不起作用的解决方案。
在我的应用程序中,我有两个页面:主页和搜索。该应用程序由几个不同的组件层组成,例如:App.js -> imports Home.js -> imports Body.js。 App.js 使用 React Router 定义路由。主页的主体包含一个搜索栏。执行搜索时,应用程序获取数据并需要将此数据传递到将显示它的搜索页面。请参阅以下文件:
App.js
import React from "react";
import {
BrowserRouter as Router,
Routes,
Route
} from "react-router-dom";
/* Import Components */
import Home from "./templates/home/Home.js";
import Search from "./templates/search/Search.js";
class App extends React.Component {
render() {
return (
<Router>
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/" element={<Search/>}/>
</Routes>
</Router>
);
}
}
export default App;
Home.js
import React from "react";
/* Import Components */
import Header from "../header/Header.js";
import Body from "./body/Body.js";
import Footer from "../footer/Footer.js";
class Home extends React.Component {
render() {
return (
<div>
<Header />
<Body />
<Footer />
</div>
);
}
}
export default Home;
正文
import React from "react";
import { Container, Row, Col } from "react-bootstrap";
import './body.css';
import { Navigate } from "react-router-dom";
/* Import Components */
import TitleImage from "./titleImage/TitleImage";
import SearchBar from "./searchBar/SearchBar";
import SampleOccurrence from "./sampleOccurence/SampleOccurence";
/* Import API functions */
import SpecimenSearch from "../../../api/SpecimenSearch.js";
class Body extends React.Component {
constructor(props) {
super(props);
this.state = {
searchQuery: ''
}
}
updateSearchQuery(query) {
this.setState({
searchQuery: query.target.value
});
}
handleSearch() {
const searchQuery = this.state.searchQuery;
SpecimenSearch(searchQuery, process.bind(this));
function process(result) {
this.setState({
searchResults: result
});
}
}
render() {
const items = [
'Frogger', 'Frogger', 'Frogger',
'Frogger', 'Frogger', 'Frogger',
'Frogger', 'Frogger', 'Frogger'
];
if (!this.state.searchResults) {
return (
<>
<TitleImage />
<Container fluid>
<SearchBar
onSearch={() => this.handleSearch()}
updateSearchQuery={(query) => this.updateSearchQuery(query)}
/>
<Row>
<Col md={{ span: "10", offset: "1" }} className="sampleOccurences">
<Row>
<h3 className="sampleOccurencesTitle">
Explore froggies
</h3>
</Row>
<Row>
{items.map((value, index) => {
return <SampleOccurrence />
})}
</Row>
</Col>
</Row>
</Container>
</>
);
} else {
// console.log(this.state.searchResults);
// return(
// <Navigate to="/" state={{data: this.state.searchResults}} />
// <Search searchResults={this.state.searchResults} />
// );
}
}
}
export default Body;
如您在 Body.js 中所见,我要么尝试使用 useNavigate 挂钩将页面导航到搜索并呈现 <Navigate to='/' />
元素('/' 是搜索的设置路径页)。钩子不起作用,因为钩子根据 React 组件中不允许的 React。后者在链接到搜索页面时工作正常,但无法传递数据(例如传递给 <Search />
的道具)。
如何使用 React Router 从 Body.js 导航到 <Search />
页面并传递数据(对象数组)?
为了您的目标,我不会使用 react-router 来传递数据。我会考虑使用状态管理库或上下文。
但是,您可以通过两种方式完成此操作:
- 功能组件(带钩子)
使用来自 useNavigate()
的 options.state
示例
// body.js
navigate('/search', { state: {
data: [{id: 1, value: '1'}, {id: 2, value: '2'}]
} });
// search.js
const location = useLocation();
const {data} = location.state;
// data => [{id: 1, value: '1'}, {id: 2, value: '2'}]
- Class 组件
中的 options.state
示例
// body.js
<Navigate to="/search" state={{
data: [{id: 1, value: '1'}, {id: 2, value: '2'}]
}} />
...
Tom,可以从 location
对象访问传递的路由状态,即 location.state.data
。您使用 useLocation
挂钩访问接收组件中的 location
对象。
发件人:
<Navigate to="/" state={{ data: this.state.searchResults }} />
接收者:
import { useLocation } from 'react-router-dom';
...
const { state } = useLocation();
const { data } = state || {};
如果接收组件是一个 class 组件并且不能直接使用 useLocation
那么你可以创建一个自定义的 withRouter
高阶组件来为你处理这个并通过 location
下来作为道具.
示例:
import { useLocation, /* other hooks */ } from 'react-router-dom';
const withRouter = Component => props => {
const location = useLocation();
// other hooks
return <Component {...props} {...{ location, /* ...other hooks */ }} />;
};
export default withRouter;
用这个 withRouter
HOC 装饰 Search
组件。
export default withRouter(Search);
现在 location
作为 prop 注入。通过 this.props.location.state
访问路由状态,与上面类似。
我目前正在尝试完成从组件到组件的路由并传递数据,以便新打开的组件可以使用它。经过几个小时的研究,我偶然发现了一些对我的情况不起作用的解决方案。
在我的应用程序中,我有两个页面:主页和搜索。该应用程序由几个不同的组件层组成,例如:App.js -> imports Home.js -> imports Body.js。 App.js 使用 React Router 定义路由。主页的主体包含一个搜索栏。执行搜索时,应用程序获取数据并需要将此数据传递到将显示它的搜索页面。请参阅以下文件:
App.js
import React from "react";
import {
BrowserRouter as Router,
Routes,
Route
} from "react-router-dom";
/* Import Components */
import Home from "./templates/home/Home.js";
import Search from "./templates/search/Search.js";
class App extends React.Component {
render() {
return (
<Router>
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/" element={<Search/>}/>
</Routes>
</Router>
);
}
}
export default App;
Home.js
import React from "react";
/* Import Components */
import Header from "../header/Header.js";
import Body from "./body/Body.js";
import Footer from "../footer/Footer.js";
class Home extends React.Component {
render() {
return (
<div>
<Header />
<Body />
<Footer />
</div>
);
}
}
export default Home;
正文
import React from "react";
import { Container, Row, Col } from "react-bootstrap";
import './body.css';
import { Navigate } from "react-router-dom";
/* Import Components */
import TitleImage from "./titleImage/TitleImage";
import SearchBar from "./searchBar/SearchBar";
import SampleOccurrence from "./sampleOccurence/SampleOccurence";
/* Import API functions */
import SpecimenSearch from "../../../api/SpecimenSearch.js";
class Body extends React.Component {
constructor(props) {
super(props);
this.state = {
searchQuery: ''
}
}
updateSearchQuery(query) {
this.setState({
searchQuery: query.target.value
});
}
handleSearch() {
const searchQuery = this.state.searchQuery;
SpecimenSearch(searchQuery, process.bind(this));
function process(result) {
this.setState({
searchResults: result
});
}
}
render() {
const items = [
'Frogger', 'Frogger', 'Frogger',
'Frogger', 'Frogger', 'Frogger',
'Frogger', 'Frogger', 'Frogger'
];
if (!this.state.searchResults) {
return (
<>
<TitleImage />
<Container fluid>
<SearchBar
onSearch={() => this.handleSearch()}
updateSearchQuery={(query) => this.updateSearchQuery(query)}
/>
<Row>
<Col md={{ span: "10", offset: "1" }} className="sampleOccurences">
<Row>
<h3 className="sampleOccurencesTitle">
Explore froggies
</h3>
</Row>
<Row>
{items.map((value, index) => {
return <SampleOccurrence />
})}
</Row>
</Col>
</Row>
</Container>
</>
);
} else {
// console.log(this.state.searchResults);
// return(
// <Navigate to="/" state={{data: this.state.searchResults}} />
// <Search searchResults={this.state.searchResults} />
// );
}
}
}
export default Body;
如您在 Body.js 中所见,我要么尝试使用 useNavigate 挂钩将页面导航到搜索并呈现 <Navigate to='/' />
元素('/' 是搜索的设置路径页)。钩子不起作用,因为钩子根据 React 组件中不允许的 React。后者在链接到搜索页面时工作正常,但无法传递数据(例如传递给 <Search />
的道具)。
如何使用 React Router 从 Body.js 导航到 <Search />
页面并传递数据(对象数组)?
为了您的目标,我不会使用 react-router 来传递数据。我会考虑使用状态管理库或上下文。
但是,您可以通过两种方式完成此操作:
- 功能组件(带钩子) 使用来自 useNavigate() 的
options.state
示例
// body.js
navigate('/search', { state: {
data: [{id: 1, value: '1'}, {id: 2, value: '2'}]
} });
// search.js
const location = useLocation();
const {data} = location.state;
// data => [{id: 1, value: '1'}, {id: 2, value: '2'}]
- Class 组件
options.state
示例
// body.js
<Navigate to="/search" state={{
data: [{id: 1, value: '1'}, {id: 2, value: '2'}]
}} />
...
Tom,可以从 location
对象访问传递的路由状态,即 location.state.data
。您使用 useLocation
挂钩访问接收组件中的 location
对象。
发件人:
<Navigate to="/" state={{ data: this.state.searchResults }} />
接收者:
import { useLocation } from 'react-router-dom';
...
const { state } = useLocation();
const { data } = state || {};
如果接收组件是一个 class 组件并且不能直接使用 useLocation
那么你可以创建一个自定义的 withRouter
高阶组件来为你处理这个并通过 location
下来作为道具.
示例:
import { useLocation, /* other hooks */ } from 'react-router-dom';
const withRouter = Component => props => {
const location = useLocation();
// other hooks
return <Component {...props} {...{ location, /* ...other hooks */ }} />;
};
export default withRouter;
用这个 withRouter
HOC 装饰 Search
组件。
export default withRouter(Search);
现在 location
作为 prop 注入。通过 this.props.location.state
访问路由状态,与上面类似。