从 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 传递多个参数(从消费者到提供者)?

无法使用React redux读取未定义的地图属性

React / Redux - 无法读取未定义的属性“XXX”

无法读取 React 中未定义的属性“映射”

React 无法读取未定义的属性映射