在 react-infinite-scroll-component 中的每个新搜索中替换获取的搜索结果
Replace fetched search results on each new search in react-infinite-scroll-component
在这个应用程序中,我从 Unsplash API(使用 Express 后端,React 前端)获取图像。在页面加载时,会出现一般图像(在 react-infinite-scroll-component
内呈现)。如果您搜索某个术语,search
状态会从 false 变为 true。我使用三元运算符有条件地渲染无限滚动组件内的图像:
{this.state.newSearch || this.state.search ? this.state.searchImages.map(image =>
<Image key={image.id} image={image} />
) : this.state.images.map(image =>
<Image key={image.id} image={image} />
)}
首先加载的图像(来自 componentDidMount
)在您输入输入并按回车键后被替换,但如果您输入其他内容并按回车键,新的搜索结果将添加到末尾.相反,我想替换以前的搜索结果。我一直在努力弄清楚如何实现这一目标。我尝试添加 newSearch
状态并在 handleSubmit
中设置 searchImages: []
和 searchStart: 1
,但两者都没有任何区别。作为 React 新手,我还尝试在无限滚动组件中的图像渲染后将 newSearch
设置回 false,这由于无限循环而破坏了应用程序。
如有任何帮助,我们将不胜感激。
家长:
export class Images extends Component {
state = {
images: [],
searchImages: [],
count: 30,
start: 1,
searchStart: 1,
term: '',
search: false,
newSearch: false
};
componentDidMount() {
const { count, start } = this.state;
axios
.get(`/api/photos?count=${count}&start=${start}`)
.then(res => this.setState({ images: res.data }));
}
fetchImages = () => {
const { count, start, images } = this.state;
// Will be at 1, then 31 (1 + 30), then 61 (31 + 30), and so forth
this.setState({ start: start + count });
axios
.get(`/api/photos?count=${count}&start=${start}`)
.then(res =>
this.setState({ images: images.concat(res.data) })
);
}
fetchSearchImages = () => {
const { searchStart, count, term, searchImages } = this.state;
this.setState({
searchStart: searchStart + count
});
axios
.get(`/api/photos/search?term=${term}&count=${count}&start=${searchStart}`)
.then(res =>
this.setState({
searchImages: searchImages.concat(res.data.results)
})
);
}
handleSubmit = () => {
this.setState({
searchImages: [],
searchStart: 1,
search: true,
newSearch: true
});
this.fetchSearchImages();
}
handleInputChange = (e) => {
this.setState({
term: e
});
}
render() {
return (
<>
<SearchInput onSearch={this.handleInputChange} onFormSubmit={this.handleSubmit} term={this.state.term} />
<div className="images">
<InfiniteScroll
dataLength={this.state.newSearch || this.state.search ? this.state.searchImages.length : this.state.images.length}
next={this.state.search ? this.fetchSearchImages : this.fetchImages}
hasMore={true}
loader={
<div className="loader-dots">
<span className="loader-dot"></span>
<span className="loader-dot"></span>
<span className="loader-dot"></span>
<span className="loader-dot"></span>
</div>
}
>
{this.state.newSearch || this.state.search ? this.state.searchImages.map(image =>
<Image key={image.id} image={image} />
) : this.state.images.map(image =>
<Image key={image.id} image={image} />
)}
</InfiniteScroll>
</div>
</>
);
}
}
子搜索组件:
const SearchInput = props => {
const onSubmit = e => {
// Prevents GET request/page refresh on submit
e.preventDefault();
props.onFormSubmit();
};
return (
<form onSubmit={onSubmit}>
<div className="control">
<input autoFocus value={props.term} onChange={e => props.onSearch(e.target.value)} className="input" type="text" placeholder="Search" />
</div>
</form>
);
}
我认为你的逻辑没有任何问题,除了这部分:
this.setState({
searchImages: searchImages.concat(res.data.results)
})
将新的搜索结果与之前的搜索结果相连接,而您只需替换它们即可:
this.setState({
searchImages: res.data.results
})
fetchSearchImages
中的当前代码依赖于 React 真正设置它之前的状态。我已将 PR 发送到您的存储库,以便仅在设置状态后通过使用 setState
.
的回调参数调用 fetchSearchImages
基本上就是这段代码
handleSubmit = () => {
this.setState({
searchImages: [],
searchStart: 1,
search: true,
newSearch: true
});
this.fetchSearchImages();
}
需要改成这样:
handleSubmit = () => {
this.setState({
searchImages: [],
searchStart: 1,
search: true,
newSearch: true
}, this.fetchSearchImages);
}
在这个应用程序中,我从 Unsplash API(使用 Express 后端,React 前端)获取图像。在页面加载时,会出现一般图像(在 react-infinite-scroll-component
内呈现)。如果您搜索某个术语,search
状态会从 false 变为 true。我使用三元运算符有条件地渲染无限滚动组件内的图像:
{this.state.newSearch || this.state.search ? this.state.searchImages.map(image =>
<Image key={image.id} image={image} />
) : this.state.images.map(image =>
<Image key={image.id} image={image} />
)}
首先加载的图像(来自 componentDidMount
)在您输入输入并按回车键后被替换,但如果您输入其他内容并按回车键,新的搜索结果将添加到末尾.相反,我想替换以前的搜索结果。我一直在努力弄清楚如何实现这一目标。我尝试添加 newSearch
状态并在 handleSubmit
中设置 searchImages: []
和 searchStart: 1
,但两者都没有任何区别。作为 React 新手,我还尝试在无限滚动组件中的图像渲染后将 newSearch
设置回 false,这由于无限循环而破坏了应用程序。
如有任何帮助,我们将不胜感激。
家长:
export class Images extends Component {
state = {
images: [],
searchImages: [],
count: 30,
start: 1,
searchStart: 1,
term: '',
search: false,
newSearch: false
};
componentDidMount() {
const { count, start } = this.state;
axios
.get(`/api/photos?count=${count}&start=${start}`)
.then(res => this.setState({ images: res.data }));
}
fetchImages = () => {
const { count, start, images } = this.state;
// Will be at 1, then 31 (1 + 30), then 61 (31 + 30), and so forth
this.setState({ start: start + count });
axios
.get(`/api/photos?count=${count}&start=${start}`)
.then(res =>
this.setState({ images: images.concat(res.data) })
);
}
fetchSearchImages = () => {
const { searchStart, count, term, searchImages } = this.state;
this.setState({
searchStart: searchStart + count
});
axios
.get(`/api/photos/search?term=${term}&count=${count}&start=${searchStart}`)
.then(res =>
this.setState({
searchImages: searchImages.concat(res.data.results)
})
);
}
handleSubmit = () => {
this.setState({
searchImages: [],
searchStart: 1,
search: true,
newSearch: true
});
this.fetchSearchImages();
}
handleInputChange = (e) => {
this.setState({
term: e
});
}
render() {
return (
<>
<SearchInput onSearch={this.handleInputChange} onFormSubmit={this.handleSubmit} term={this.state.term} />
<div className="images">
<InfiniteScroll
dataLength={this.state.newSearch || this.state.search ? this.state.searchImages.length : this.state.images.length}
next={this.state.search ? this.fetchSearchImages : this.fetchImages}
hasMore={true}
loader={
<div className="loader-dots">
<span className="loader-dot"></span>
<span className="loader-dot"></span>
<span className="loader-dot"></span>
<span className="loader-dot"></span>
</div>
}
>
{this.state.newSearch || this.state.search ? this.state.searchImages.map(image =>
<Image key={image.id} image={image} />
) : this.state.images.map(image =>
<Image key={image.id} image={image} />
)}
</InfiniteScroll>
</div>
</>
);
}
}
子搜索组件:
const SearchInput = props => {
const onSubmit = e => {
// Prevents GET request/page refresh on submit
e.preventDefault();
props.onFormSubmit();
};
return (
<form onSubmit={onSubmit}>
<div className="control">
<input autoFocus value={props.term} onChange={e => props.onSearch(e.target.value)} className="input" type="text" placeholder="Search" />
</div>
</form>
);
}
我认为你的逻辑没有任何问题,除了这部分:
this.setState({
searchImages: searchImages.concat(res.data.results)
})
将新的搜索结果与之前的搜索结果相连接,而您只需替换它们即可:
this.setState({
searchImages: res.data.results
})
fetchSearchImages
中的当前代码依赖于 React 真正设置它之前的状态。我已将 PR 发送到您的存储库,以便仅在设置状态后通过使用 setState
.
fetchSearchImages
基本上就是这段代码
handleSubmit = () => {
this.setState({
searchImages: [],
searchStart: 1,
search: true,
newSearch: true
});
this.fetchSearchImages();
}
需要改成这样:
handleSubmit = () => {
this.setState({
searchImages: [],
searchStart: 1,
search: true,
newSearch: true
}, this.fetchSearchImages);
}