我正在学习React,并且正在构建一个简单的应用来试验道具。我有一个输入字段,可根据用户输入搜索数据库,我想将结果显示在另一个组件中,该组件将在搜索后加载,并且是Search组件的子组件。当我将数据从搜索组件传递到SearchResultsPage组件时,我得到了Cannot read property 'map' of undefined
,但我不知道为什么,如何通过道具正确传递数据?
这是我的搜索组件:
import React, { Component } from "react";
import Spinner from '../../components/Spinner/Spinner.jsx';
import SearchResultsPage from '../SearchResultsPage/SearchResultsPage.jsx';
import { Link } from 'react-router-dom';
import axios from "axios";
class Search extends Component {
constructor(props) {
super(props);
this.state = {
searchResults: [],
isLoading: false,
isSearchStringFound: true
}
}
getSearchQuery = (event) => {
const SEARCH_RESULTS_ENDPOINT = process.env.REACT_APP_SEARCH_ENDPOINT;
const searchString = document.querySelector(".search-input").value;
if (event.keyCode === 13) {
this.setState({ ...this.state, isLoading: true });
axios.post(SEARCH_RESULTS_ENDPOINT, {
searchString: searchString,
}).then(response => {
this.setState({ ...this.state, searchResults: response.data });
if (response.data.length === 0) {
this.setState({ ...this.state, isSearchStringFound: false });
}
else if (response.data.length > 0) {
this.setState({ ...this.state, isSearchStringFound: true });
}
this.setState({ ...this.state, isLoading: false });
window.location.href = "/blog/searchResults"
});
}
};
render() {
if (this.state.isLoading) {
return <Spinner />
}
return (
<div>
<input
type="text"
placeholder="Search"
className="search-input"
onKeyDown={(e) => this.getSearchQuery(e)}
/>
<div>
<SearchResultsPage
searchResults={this.state.searchResults}
isSearchStringFound={this.state.isSearchStringFound}
/>
</div>
</div>
);
}
}
export default Search;
和我的ResultsPage组件:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Footer from '../Footer/Footer.jsx';
import CustomHeader from '../CustomHeader/CustomHeader.jsx';
let title = 'Blog'
class SearchResultsPage extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<CustomHeader
title={title}
/>
<div>
{this.props.isSearchStringFound === false ? <div className="no-results-found">No results were found</div> : this.props.searchResults.map(result => (
<div key={result._id} >
<img src={result.picture} alt="avatar" />
<div >
<div>
<h2>{result.title}</h2>
<p>{result.date}</p>
<p>{result.postContent}</p>
<Link to={`/post/${result._id}`} className="read-more-btn">
<button className="read-more-btn">Read more</button>
</Link>
</div>
</div>
</div>
))}
</div>
<Footer />
</div>
)
}
};
export default SearchResultsPage;
答案 0 :(得分:0)
您没有正确更新状态。事件处理程序中的状态更新是批量的并且是异步的,这就是为什么状态未正确更新导致子组件出错的原因
也不需要使用this.state
来传播this.setState
,并且由于已经渲染了组件,因此在axios调用之后不需要重定向。
您可以通过单个setState调用来更新状态,例如
axios.post(SEARCH_RESULTS_ENDPOINT, {
searchString: searchString,
}).then(response => {
const data = response.data;
let isSearchStringFound;
if (response.data.length === 0) {
isSearchStringFound= false;
}
else if (response.data.length > 0) {
isSearchStringFound = true;
}
this.setState({ isSearchStringFound, searchResults: data, isLoading: false });
});