从 React Context 消费返回无法读取未定义的属性“地图”
Posted
技术标签:
【中文标题】从 React Context 消费返回无法读取未定义的属性“地图”【英文标题】:Consuming from React Context returns Cannot read property 'map' of undefined 【发布时间】:2020-09-17 22:44:35 【问题描述】:我正在尝试使用 Context 在 React 中的两个组件之间传递数据。我要传递的数据是一个数组searchResults
。我已经设置了上下文和所有内容,但是当我尝试在我的第二个组件中使用该数组时,我得到Cannot read property 'map' of undefined
,我如何才能在我通过上下文发送的第二个组件中使用该数组?
这是我的第一个组件:
import React, Component from "react";
import axios from "axios";
export const SearchContext = React.createContext();
class Search extends Component
state =
searchResults: [],
isSearched: false
getSearchQuery = (event) =>
const queryString = document.querySelector(
".search-input"
).value;
if (event.keyCode === 13)
axios.post("http://localhost:3001/search",
queryString: queryString,
).then(response =>
this.setState( ...this.state, searchResults: response.data );
);
this.setState( ...this.state, isSearched: true );
window.location.href = '/blog/searchResults'
;
render()
console.log(this.state.searchResults)
return (
<SearchContext.Provider value=this.state.searchResults>
<input
type="text"
className="search-input"
onKeyDown=(e) => this.getSearchQuery(e)
/>
</SearchContext.Provider>
);
export default Search;
以及我应该使用数组的第二个组件:
import React, Component from 'react';
import Footer from '../Footer/Footer.jsx';
import CustomHeader from '../CustomHeader/CustomHeader.jsx';
import SearchContext from '../../components/Search/Search.jsx';
let title = 'Blog'
class SearchResultsPage extends Component
render()
return (
<div>
<CustomHeader
title=title
/>
<SearchContext.Consumer>
(value) => value.map(result => (
<div key=result._id>
<div>
</div>
<article>
value.postContent
</article>
</div>
)
)
</SearchContext.Consumer>
<Footer />
</div>
)
;
【问题讨论】:
【参考方案1】:我认为需要退货
<SearchContext.Consumer>
value.map(result =>
return ( <div key=result._id>
<div>
</div>
<article>
value.postContent
</article>
</div>
)
)
</SearchContext.Consumer>
【讨论】:
【参考方案2】:上下文使用者将一个函数作为子函数,将上下文值传递给该函数。你可以像下面这样写
<SearchContext.Consumer>
(value) => value.map(result => (
<div key=result._id>
<div>
</div>
<article>
value.postContent
</article>
</div>
)
)
</SearchContext.Consumer>
更新:基于您的编辑
您的 SearchResultsPage 未呈现为 Search 组件的子组件,并且为了使上下文使用者正常工作,它需要层次结构中的上下文提供程序。
请像这样渲染 SearchResults 页面
<Search>
<SearchResultsPage />
</Search>
在搜索组件中,您将不得不使用和渲染子组件
render()
console.log(this.state.searchResults)
return (
<SearchContext.Provider value=this.state.searchResults>
<input
type="text"
className="search-input"
onKeyDown=(e) => this.getSearchQuery(e)
/>
this.props.children
</SearchContext.Provider>
);
【讨论】:
我现在试过了,但它给了我Cannot read property 'map' of undefined
是上下文中的 searchResults,在 api 请求后可能会设置为 undefined。你能验证一下吗
还有一件事,您的搜索结果页面需要是 Search 组件的子组件
上下文的想法不是在全球范围内共享数据,因此被用于不是孩子的组件吗?如果 SearchResults 是一个孩子,那么我将只使用道具而不是上下文。我编辑了我的 SearchResults 组件,因为我不需要 Search,因为它是一个单独的组件
实际上不是。如果你也看一下 redux,它是一个数据存储,它还提供了一个 Provider,它是在上下文之上实现的,需要出现在顶层。 Context 的逻辑也类似。但是,组件不必是直接子级,而是可以处于任何深度。以上是关于从 React Context 消费返回无法读取未定义的属性“地图”的主要内容,如果未能解决你的问题,请参考以下文章
反应钩子:useState/context;无法读取未定义的属性“头像”/如何更新嵌套对象
如何通过 React Context 传递多个参数(从消费者到提供者)?