reactjs - 用参数反应路由器 dom 链接并不总是有效
问题描述
我写了一个简单的搜索组件,在反应中带有自动建议,它调用 themoviedb。我正在使用 react-router-dom 并在 app.js 中定义了这样的路由参数:
<Route path="/:id" component={SomeComponent} />
搜索组件如下所示:
import React, { Component, Fragment } from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
import axios from "axios";
const SuggestionsResult = styled.ul`
text-decoration: none;
list-style: none;
text-align: left;
display: flex;
flex-direction: column;
width: 100%;
`;
const ResultItem = styled.li`
border-bottom: 0.0625rem solid hsla(0, 0%, 100%, 0.12);
padding: 10px 0 10px;
padding-left: 2px;
font-size: 1em;
cursor: pointer;
&:hover {
background: hsla(0, 0%, 100%, 0.12);
}
`;
export default class Search extends Component {
state = {
query: "",
results: [],
showSuggestions: false
};
handleInputChange = () => {
this.setState(
{
query: this.search.value
},
() => {
if (this.state.query && this.state.query.length > 1) {
if (this.state.query.length % 2 === 0) {
axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=en-US&query=${
this.state.query
}&page=1&include_adult=false`
)
.then(({ data }) => {
this.setState({
results: data.results,
showSuggestions: !this.state.showSuggestions
});
});
}
} else if (!this.state.query) {
}
}
);
};
handleSuggestionClick = e => {
this.setState({ showSuggestions: false });
};
render() {
return (
<Fragment>
<input
placeholder="Search for a movie..."
ref={input => (this.search = input)}
onChange={this.handleInputChange}
/>
{this.state.showSuggestions && (
<Suggestions
results={this.state.results}
handleSuggestionClick={this.handleSuggestionClick}
/>
)}
</Fragment>
);
}
}
const Suggestions = ({ results, handleSuggestionClick }) => {
const options = results.map(r => (
<ResultItem key={r.id}>
<Link onClick={handleSuggestionClick} to={`/${r.id}`}>
{r.title}
</Link>
</ResultItem>
));
return <SuggestionsResult>{options}</SuggestionsResult>;
};
我的问题是单击链接时它会更改 url 但它仍然在同一个站点上。如果我不使用 react-router-dom Link 组件而只使用一个元素,它可以正常工作,但一切都会重新渲染。
** 在 app.js 中更新我的 react-router 代码
<Router>
<Switch>
<Route exact path="/" component={MoviesList} />
<Route path="/:id" component={MovieDetail} />
</Switch>
</Router>
解决方案
Suggestions 组件没有接收到 Router 属性,因此会导致此问题。withRouter
用HOC包装你的 Suggestions 组件。还要确保将 Search 组件呈现为子组件或Router
组件
import React, { Component, Fragment } from "react";
import { Link, withRouter } from "react-router-dom";
import styled from "styled-components";
import axios from "axios";
const SuggestionsResult = styled.ul`
text-decoration: none;
list-style: none;
text-align: left;
display: flex;
flex-direction: column;
width: 100%;
`;
const ResultItem = styled.li`
border-bottom: 0.0625rem solid hsla(0, 0%, 100%, 0.12);
padding: 10px 0 10px;
padding-left: 2px;
font-size: 1em;
cursor: pointer;
&:hover {
background: hsla(0, 0%, 100%, 0.12);
}
`;
export default class Search extends Component {
state = {
query: "",
results: [],
showSuggestions: false
};
handleInputChange = () => {
this.setState(
{
query: this.search.value
},
() => {
if (this.state.query && this.state.query.length > 1) {
if (this.state.query.length % 2 === 0) {
axios
.get(
`https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=en-US&query=${
this.state.query
}&page=1&include_adult=false`
)
.then(({ data }) => {
this.setState({
results: data.results,
showSuggestions: !this.state.showSuggestions
});
});
}
} else if (!this.state.query) {
}
}
);
};
handleSuggestionClick = e => {
this.setState({ showSuggestions: false });
};
render() {
return (
<Fragment>
<input
placeholder="Search for a movie..."
ref={input => (this.search = input)}
onChange={this.handleInputChange}
/>
{this.state.showSuggestions && (
<Suggestions
results={this.state.results}
handleSuggestionClick={this.handleSuggestionClick}
/>
)}
</Fragment>
);
}
}
const Suggestions = withRouter(({ results, handleSuggestionClick }) => {
const options = results.map(r => (
<ResultItem key={r.id}>
<Link onClick={handleSuggestionClick} to={`/${r.id}`}>
{r.title}
</Link>
</ResultItem>
));
return <SuggestionsResult>{options}</SuggestionsResult>;
});
推荐阅读
- openebs - 我无法使用自定义 cStor 存储池声明 cStor 卷
- python - Python实例变量赋值标准编程实践
- android - 要将敏感信息保存在 Android 内部存储中,我们需要注意哪些安全步骤?
- ckeditor5 - CKEditor 5 将选定的内容从一个编辑器复制到另一个编辑器
- android - 从 python 中的自定义 API 下载文件
- javascript - 多个测试可以使用同一个数据提供者函数吗
- python - Pandas Dataframe groupby,然后根据菜单或文本选项进行过滤
- php - Magento Open Source 2.3 - CSS 和 JS 未加载
- android - 当用户尚未在 android 中安装应用程序时,Firebase 深层链接参数未接收?
- android - SharedPreferences 不更新值