TypeError:无法读取属性“包含”为null

时间:2020-05-03 17:03:53

标签: reactjs gatsby algolia

我正在关注this algolia tutorial,对盖茨比还是陌生人。下面的代码目前似乎引起问题。

我已经从search / index.js文件中添加了其余代码...

import React, { useState, useEffect, createRef } from "react"
import { InstantSearch, Index, Hits, connectStateResults } from "react-instantsearch-dom"
import algoliasearch from "algoliasearch/lite"

import { Root, HitsWrapper, PoweredBy } from "./styles"
import Input from "./input"
import * as hitComps from "./hitComps"

const Results = connectStateResults(
    ({ searchState: state, searchResults: res, children }) =>
        res && res.nbHits > 0 ? children : `No results for '${state.query}'`
)

const Stats = connectStateResults(
    ({ searchResults: res }) =>
        res && res.nbHits > 0 && `${res.nbHits} result${res.nbHits > 1 ? `s` : ``}`
)

const useClickOutside = (ref, handler, events) => {
    if (!events) events = [`mousedown`, `touchstart`]
    const detectClickOutside = event =>
        !ref.current.contains(event.target) && handler()
    useEffect(() => {
        for (const event of events)
            document.addEventListener(event, detectClickOutside)
        return () => {
            for (const event of events)
                document.removeEventListener(event, detectClickOutside)
        }
    })
}

export default function Search({ indices, collapse, hitsAsGrid }) {
    const ref = createRef()
    const [query, setQuery] = useState(``)
    const [focus, setFocus] = useState(false)
    const searchClient = algoliasearch(
        process.env.GATSBY_ALGOLIA_APP_ID,
        process.env.GATSBY_ALGOLIA_SEARCH_KEY
    )
    useClickOutside(ref, () => setFocus(false))
    return (
        <InstantSearch
            searchClient={searchClient}
            indexName={indices[0].name}
            onSearchStateChange={({ query }) => setQuery(query)}
            root={{ Root, props: { ref } }}
        >
            <Input onFocus={() => setFocus(true)} {...{ collapse, focus }} />
            <HitsWrapper show={query.length > 0 && focus} asGrid={hitsAsGrid}>
                {indices.map(({ name, title, hitComp }) => (
                    <Index key={name} indexName={name}>
                        <header>
                            <h3>{title}</h3>
                            <Stats />
                        </header>
                        <Results>
                            <Hits hitComponent={hitComps[hitComp](() => setFocus(false))} />
                        </Results>
                    </Index>
                ))}
                <PoweredBy />
            </HitsWrapper>
        </InstantSearch>
    )
}

页面已加载,但随后单击屏幕上的任何位置都会出现以下错误...

 TypeError: Cannot read property 'contains' of null
 HTMLDocument.detectClickOutside
 src/components/search/index.js:21
  18 | 
  19 | const useClickOutside = (ref, handler, events) => {
  20 |     if (!events) events = [`mousedown`, `touchstart`]
  21 |     const detectClickOutside = event =>
  22 |         !ref.current.contains(event.target) && handler()
  23 |     useEffect(() => {
  24 |         for (const event of events)

我确定这是一个非常基本的错误。如果有人有任何提示,我将不胜感激。谢谢。

2 个答案:

答案 0 :(得分:1)

问题可能出在您定义引用时,请使用Facebook的最佳做法。

我认为您可能会做出类似的事情:

const ref = React.createRef()

<InstanceSearch 
/* Your rest of your props */
ref={ref}
/>

答案 1 :(得分:1)

我遇到了同样的问题,并通过在search / index.js中将ref={ref}添加到<HitsWrapper>来解决了这个问题。

<HitsWrapper ref = {ref} show={query.length > 0 && focus} asGrid={hitsAsGrid}>