反应上下文:TypeError:无法读取未定义的属性“areResultsVisible”

亚历克斯·弗里曼

有人可以帮帮我吗?我试图通过上下文将数据从一个组件传递到另一个组件(从 Search.js 到 Container.js)。但是,我收到了类型错误。我在网上搜索了很多问题,但没有找到答案。对不起,如果是幼稚的问题,我是新来的。

搜索.js:

import React, { Component } from 'react'
import { StyledFormSearchBar } from '../styles'
import { data } from '../data'

const SearchContext = React.createContext()

export default class Search extends Component {
  constructor() {
    super()
    this.state = {
      value: '',
      results: [],
      areResultsVisible: false
    }

    this.handleSearch = this.handleSearch.bind(this)
  }

  handleSearch(e) {
    this.setState = {
      value: e.target.value,
      results: data.filter(item => {
        return item.title.toLowerCase().includes(e.target.value.toLowerCase())
      }),
      areResultsVisible: true
    }
  }

  render() {
    return (
      <StyledFormSearchBar>
        <input type="search" name="search" className="border border-dark rounded" onSubmit={this.handleSearch}/>
        <button type="submit" value="submit" className="bg-warning border-0 text-danger rounded-right position-relative">
          <i className="fas fa-search"></i>
        </button>

        <SearchContext.Provider value = {{
          ...this.state,
          handleSearch: this.handleSearch
        }}>
          {this.props.children}
        </SearchContext.Provider>
        
      </StyledFormSearchBar>
    )
  }
}

const SearchContextConsumer = SearchContext.Consumer

export { SearchContextConsumer }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

容器.js:

import React from 'react'
import { Route, Switch } from "react-router-dom"
import { StyledDivGridContainer } from './styles'
import { SearchContextConsumer } from './header/Search'

import Carousel from './container/Carousel'
import MobilePhonesDiscount from './container/products/carousel/MobilePhonesDiscount'
import LaptopsDiscount from './container/products/carousel/LaptopsDiscount'
import TabletsDiscount from './container/products/carousel/TabletsDiscount'
import Products from './container/Products'
import SearchResults from './container/SearchResults'
import MobilePhones from './container/products/MobilePhones'
import Laptops from './container/products/Laptops'
import Tablets from './container/products/Tablets'
import ProductPage from './container/ProductPage'
import About from './container/About'
import ContactUs from './container/ContactUs'

export default function Container() {
  return (
    <StyledDivGridContainer>
      <div className="no-gutters justify-content-between">
        <SearchContextConsumer>
          {
            value => {
              return (
                !value.areResultsVisible 
                ? <Switch>
                    <Route exact path="/" component={Carousel}/>
                    <Route exact path="/" component={Products}/>
                  </Switch>                
                : <Route exact path="/" component={SearchResults}/>
              )
            }
          }
        </SearchContextConsumer>
        <Route path="/mobile_phones_discount" component={MobilePhonesDiscount}/>
        <Route path="/laptops_discount" component={LaptopsDiscount}/>
        <Route path="/tablets_discount" component={TabletsDiscount}/>
        <Route path="/mobile_phones" component={MobilePhones}/>
        <Route path="/laptops" component={Laptops}/>
        <Route path="/tablets" component={Tablets}/>
        <Route path="/product_page" component={ProductPage}/>
        <Route path="/about" component={About}/>
        <Route path="/contact_us" component={ContactUs}/>
      </div>
    </StyledDivGridContainer>
  )
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Search.jsHeader.js 中

import React, { Component } from 'react'
import { StyledHeader,
         StyledSpanAccount } from './styles'
import { Link } from "react-router-dom"

import Catalogue from "./header/Catalogue"
import Search from "./header/Search"

export default class Header extends Component {
  render() {
    return (
      <StyledHeader className="d-flex w-100 bg-light shadow justify-content-center">
        <div className="d-flex flex-wrap justify-content-around align-items-center">
          <div className="my-1 mr-3">
            <Link to="/" className="logo">
              <img src={require('../img/logo.webp')} alt="logo" className="img-tumbnail"/>
            </Link>
          </div>
          <Catalogue/>

          <Search/>
          
          <div className="d-flex my-3">
            <a href="#"><i className="fas fa-shopping-cart"></i></a>
            <a href="#"><i className="fas fa-user-alt ml-3"></i></a>
            <a href="#" className="d-flex flex-nowrap">
              <StyledSpanAccount className="ml-2">Log in</StyledSpanAccount>
            </a>
            <a href="#" className="d-flex flex-nowrap">
              <StyledSpanAccount className="ml-2">Sing up</StyledSpanAccount>
            </a>
          </div>
        </div>
      </StyledHeader>
    )
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Container.jsHeader.js 附近的App.js 中

import React from 'react';
import { Route } from "react-router-dom";
import { StyledDivWrapper } from './components/styles';

import Header from './components/Header';
import Container from './components/Container';
import Footer from './components/Footer';

export default function App() {
  return (
    <StyledDivWrapper className="d-flex flex-column">
      <Route path="/" component={Header}/>
      <Route path="/" component={Container}/>
      <Route path="/" component={Footer}/>
    </StyledDivWrapper>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

错误截图 我的文件夹树

舒巴姆·哈特里

问题是您的 Container 组件不在 SearchContext.Provider 中。为了确保您的代码正常工作,您必须将 SearchContext Provider 直接放在您的 App 组件中,以便它是 Search 和 Container 组件的共同父级

首先,在不同的文件中创建上下文

// SearchContext.js

export const SearchContext = React.createContext();
const SearchContextConsumer = SearchContext.Consumer

export { SearchContextConsumer }

其次,创建一个充当提供者的组件

// SearchProvider.js

class SearchProvider extends React.Component {
   constructor() {
    super()
    this.state = {
      value: '',
      results: [],
      areResultsVisible: false
    }

    this.handleSearch = this.handleSearch.bind(this)
  }

  handleSearch(e) {
    this.setState = {
      value: e.target.value,
      results: data.filter(item => {
        return item.title.toLowerCase().includes(e.target.value.toLowerCase())
      }),
      areResultsVisible: true
    }
  }

  render() {
    return (
       <SearchContext.Provider value = {{
          ...this.state,
          handleSearch: this.handleSearch
        }}>
          {this.props.children}
       </SearchContext.Provider>        
    )
  }
}

现在您的搜索组件将只是

// Search.js


export default class Search extends Component {
  render() {
    return (
       <SearchContext.Consumer>
         {({handleSearch}) => (
             <StyledFormSearchBar>
                <input type="search" name="search" className="border border-dark rounded" onSubmit={handleSearch}/>
                <button type="submit" value="submit" className="bg-warning border-0 text-danger rounded-right position-relative">
                  <i className="fas fa-search"></i>
                </button>
              </StyledFormSearchBar>
          )}
        </SearchContext.Consumer>
    )
  }
}

也不,您可以在 App.js 中使用您的 SearchProvider,例如

export default function App() {
    return (
       <SearchProvider>
          <StyledDivWrapper className="d-flex flex-column">
              <Route path="/" component={Header}/>
              <Route path="/" component={Container}/>
              <Route path="/" component={Footer}/>
          </StyledDivWrapper>
       </SearchProvider>
    );
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

反应-TypeError:无法读取未定义的属性'props'

TypeError:无法读取未定义的属性“名称”-反应

无法读取未定义的属性...(上下文中的属性/值)

反应:TypeError:无法读取未定义的属性“ setState”

反应承诺:TypeError:无法读取未定义的属性“ then”

反应上下文状态属性未定义

反应TypeError:无法读取未定义的属性“替换”

反应上下文返回未定义

反应上下文-'contextType'未定义

反应:TypeError:无法读取未定义的属性“ productID”

反应-TypeError:无法读取未定义的属性

TypeError:无法读取未定义反应错误的属性“名称”

反应上下文返回未定义

反应TypeError:无法读取未定义的属性'getDates'

TypeError:无法读取未定义反应命中的属性“ title”

反应本机TypeError:无法读取未定义的属性'timeSlots'

反应上下文-“ this”未定义

无法读取未定义的属性“上下文”-GraphQL

反应:TypeError:无法读取未定义的属性“ newCases”

反应TypeError:无法读取未定义的属性'map'

反应上下文未定义

反应-TypeError:无法读取未定义的属性“图像”

反应:TypeError:无法读取未定义的属性“ renderInput”

TypeError:无法读取VueJS上下文中未定义的属性“替换”

无法从Promise,上下文API(反应钩子)读取未定义的属性“代码”

传递上下文时无法读取未定义的属性“参数” - Google 上的操作

构造函数中未定义上下文 - 反应

反应 - 错误:TypeError:无法读取未定义的属性(读取“then”)

TypeError:无法读取未定义的 React Native 上下文的属性“提供者”