Javascript 将道具从父级传递到子级将返回React中未定义的道具
我正在学习React,我正在构建一个简单的应用程序来试验道具。我有一个基于用户输入搜索数据库的输入字段,我希望在搜索后加载的另一个组件中显示结果,该组件是搜索组件的子组件。当我将数据从搜索组件传递到SearchResultsPage组件时,我发现Javascript 将道具从父级传递到子级将返回React中未定义的道具,javascript,reactjs,Javascript,Reactjs,我正在学习React,我正在构建一个简单的应用程序来试验道具。我有一个基于用户输入搜索数据库的输入字段,我希望在搜索后加载的另一个组件中显示结果,该组件是搜索组件的子组件。当我将数据从搜索组件传递到SearchResultsPage组件时,我发现无法读取未定义的属性“map”,我不知道为什么,如何通过道具正确传递数据? 这是我的搜索组件: import React, { Component } from "react"; import Spinner from '../../components
无法读取未定义的属性“map”,我不知道为什么,如何通过道具正确传递数据?
这是我的搜索组件:
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;
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;
import React,{Component}来自“React”;
从“../../components/Spinner/Spinner.jsx”导入微调器;
从“../SearchResultsPage/SearchResultsPage.jsx”导入SearchResultsPage;
从'react router dom'导入{Link};
从“axios”导入axios;
类搜索扩展组件{
建造师(道具){
超级(道具);
此.state={
搜索结果:[],
孤岛加载:false,
IsSearchString发现:正确
}
}
getSearchQuery=(事件)=>{
const SEARCH\u RESULTS\u ENDPOINT=process.env.REACT\u APP\u SEARCH\u ENDPOINT;
const searchString=document.querySelector(“.search input”).value;
如果(event.keyCode===13){
this.setState({…this.state,isLoading:true});
axios.post(搜索结果){
searchString:searchString,
})。然后(响应=>{
this.setState({…this.state,searchResults:response.data});
if(response.data.length==0){
this.setState({…this.state,isSearchStringFound:false});
}
否则如果(response.data.length>0){
this.setState({…this.state,IsSearchString:true});
}
this.setState({…this.state,isLoading:false});
window.location.href=“/blog/searchResults”
});
}
};
render(){
if(此.state.isLoading){
返回
}
返回(
this.getSearchQuery(e)}
/>
);
}
}
导出默认搜索;
和我的结果页面组件:
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;
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;
import React,{Component}来自'React';
从'react router dom'导入{Link};
从“../Footer/Footer.jsx”导入页脚;
从“../CustomHeader/CustomHeader.jsx”导入CustomHeader;
让title='Blog'
类SearchResultsPage扩展组件{
建造师(道具){
超级(道具);
}
render(){
返回(
{this.props.isSearchStringFound==false?未找到任何结果:this.props.searchResults.map(结果=>(
{result.title}
{result.date}
{result.postContent}
阅读更多
))}
)
}
};
导出默认搜索结果页面;
您没有正确更新状态。事件处理程序中的状态更新是批处理的,并且是异步的,这就是为什么状态没有正确更新导致子组件中出现错误的原因
此外,不需要使用this.setState
扩展this.state
,也不需要在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 });
});
您是否确保要更新状态一次,就像this.setState({isSearchStringFound,searchResults:data,isLoading:false})代码>如果是这样,您是否记录并查看response.data从axios Request返回的内容是的,我就是这样做的您在初始渲染或调用getSearchQuery时收到错误吗。另外,除了无法读取未定义的属性映射之外,控制台中是否存在任何错误?在我键入一封信并按ENTER键后,我将收到它。您可以登录,console.log(数据,isSearchStringFound)
beforethis.setState({isSearchStringFound,searchResults:data,isLoading:false})代码>并共享结果