首页 > 解决方案 > React-router:在链接和地图匹配数据中传递道具

问题描述

我试图找出我做得不好的地方。

我有一个商店对象,它是一个内部有不同商店的数据库。感谢 react-router,我想在他们自己的页面中呈现每个商店的信息。

我已经尝试了很多方法来呈现我的细节。

总是回来的错误是我可以在我的 shopDetails 组件中读取道具或未定义状态。当我想控制台记录我的位置元素时,它显示为未定义但是当我转到我的反应开发人员工具时,我可以看到我的商店数据正确存储在我的 shopDetails props.location 中......

我真的不明白如何渲染好的数据。我打开所有其他主题而不了解如何处理我的问题。

如果你能在这方面提供帮助,那就太棒了。谢谢你的时间。

应用程序.js

 render() {
    return (
      <Router>
          <HeaderFilters
            wrapperHeaderFunction={this.wrapperHeaderFunction}
            zip_code={this.state.zip_code}
            handleChanges={this.handleChanges}
            isClicked={this.isClicked}
            filterClick={this.filterClick}
            selectedOption={this.state.selectedOption}
            moreFilterClick={this.moreFilterClick}
            filteredResults={this.state.filteredResults}
            rating={this.state.rating}
            startDate={this.state.startDate} // momentPropTypes.momentObj or null,
            startDateId="your_unique_start_date_id" // PropTypes.string.isRequired,
            endDate={this.state.endDate} // momentPropTypes.momentObj or null,
            endDateId="your_unique_end_date_id" // PropTypes.string.isRequired,
            onDatesChange={({ startDate, endDate }) =>
              this.setState({ startDate, endDate })
            } // PropTypes.func.isRequired,
            focusedInput={this.state.focusedInput} // PropTypes.oneOf([START_DATE, END_DATE]) or null,
            onFocusChange={focusedInput => this.setState({ focusedInput })} // PropTypes.func.isRequired,
          />

          {this.state.isMoreFiltersRequired ? (
            <MoreFilters
              handleChanges={this.handleChanges}
              isClicked={this.isClicked}
              filterClick={this.filterClick}
              moreFilterClick={this.moreFilterClick}
              filteredResults={this.state.filteredResults}
              rating={this.state.rating}
            />
          ) : null}
          <div>
            {this.state.login ? <Spinner animation="border" size="xl" /> : null}
          </div>


          <Switch>
            <Route
              exact
              path="/"
              render={() => (
                <ShopPreview
                  loading={this.state.loading}
                  shops={this.state.shops}
                  filteredResults={this.state.filteredResults}
                  rating={this.state.rating}
                />
              )}
            />

            <Route
              path="/search"
              render={() => (
                <ShopSearch
                  loading={this.state.loading}
                  shops={this.state.shops}
                  filteredResults={this.state.filteredResults}
                  rating={this.state.rating}
                />
              )}
            />

            <Route
              path={`/shopDetail/:id`}
              render={routeProps => (
                <ShopDetails {...routeProps} shops={this.state.shops} />
              )}
            />
          </Switch>
      </Router>
    );
  }
}

export default App;

Shops.js(呈现商店列表的组件)

 render() {
    return (
      <Container>
        <ListGroup>
          {this.props.shops.map((detail, index) => (
            <ListGroup.Item key="index">
              <Row>
                <Col>
                  <Image
                    alt=""
                    src={detail.imgURL}
                    width={150}
                    height={150}
                    rounded
                  />
                </Col>
                <Col>
                  <h3 className="shop_title">{detail.nom}</h3>
                  <StarRatings
                    rating={this.props.rating}
                    starRatedColor="#DAA520"
                    changeRating={this.changeRating}
                    numberOfStars={5}
                    starDimension="15px"
                    name="rating"
                    starSpacing="2px"
                  />
                  <p id="resume">{detail.resume}</p>
                </Col>
                <Col>
                  <Row>
                    {detail.startPrice === ""
                      ? "Sur devis"
                      : "A partir de " + detail.startPrice + " €&quot;}
                  </Row>
                  <Row>
                    {/* Make route with id, with key= detail.id */}
                    <Link
                      to={{
                        pathname: "/shopDetail/" + detail.id,
                        state: {shops : this.props.shops}
                      }}
                    >
                      <Button
                        className="detailButton"
                        key={detail.id}
                        variant="primary"
                        onClick={this.props.filterClick}
                      >
                        Détails
                      </Button>
                    </Link>
                  </Row>
                </Col>
              </Row>
            </ListGroup.Item>
          ))}
        </ListGroup>
      </Container>
    );
  }
}

export default Shops;

ShopDetails.js(根据其 URL id 呈现商店详细信息的组件)

import React, { Component } from 'react'

class ShopDetails extends Component {
    constructor(props){
      super(props)
      this.setState({
      })
    }
  render() { 
     
      console.log("Props shops: " ,this.props.shops)
      const id = window.location.pathname.replace("/shopDetail/", "");
      const data = this.props.shops
      const location = this.props.location
      console.log("Location:", location)
      const shop = data.find(s => s.id === id)
      
      return (
  <div>
    <h1>{shop.id}</h1>
    <h3>{shop.nom}</h3>
    <p>{shop.website}</p>
  </div>
)    
}}
 
export default ShopDetails

目前,我只允许渲染 id,但我无法访问我所在州的元素“商店”,这些元素存储了我的商店数据以映射到每个组件上。

编辑: 屏幕截图控制台.LOG

编辑2:

   import React, { Component } from 'react'
    
    class ShopDetails extends Component {
        constructor(props){
          super(props)
          this.setState({
            shop:{}
          })
        }
      render() { 
         
          console.log("Props shops: " ,this.props.shops)
          const id = window.location.pathname.replace("/shopDetail/", "");
          console.log("id: ", id)
          const data = this.props.shops
          console.log("data: ", data)
          const location = this.props.location.state
          console.log("Location:", location)
          const shop = data.find(s => s.id === id)
          
          return (
      <div>
      
      </div>
    )    
    }}
     
    export default ShopDetails

编辑3

开发的屏幕日志对象 1 Edit3

开发的屏幕日志对象 2 Edit3

屏幕日志对象开发3

编辑4:

const shop,终于可以在 console.log 中渲染一些东西了

问题是关于三重 = 在我的 const shop = data.find(s => s.id == id)

import React, { Component } from 'react'

class ShopDetails extends Component {
    constructor(props){
      super(props)
      this.setState({
        shop:{}
      })
    }
  render() { 
     
      console.log("Props shops: " ,this.props.shops)
      const id = window.location.pathname.replace("/shopDetail/", "");
      console.log("id: ", id)
      const data = this.props.shops
      console.log("data: ", data)
      const shop = data.find(s => s.id == id)
      console.log("shop: ", shop)
      console.log("this.props.match.params.id: ", this.props.match.params.id)
      
      return (
  <div>
     {shop.map((detail, index) => (
       <div key={index}>
         <h1>{detail.nom}</h1>
       </div>

     ))}
    <p>{data.id}</p>
  
  </div>
)    
}}
 
export default ShopDetails

现在我必须返回存储在我的 shop const 中的数据,请参见下面的 console.log(shop) 自编辑 4 的链接

截图编辑4

标签: javascriptreactjsreact-router

解决方案


您必须设置 == 而不是 === 因为您商店的 id 是一个数字,而您的 url 中的 id 是一个字符串。如果您将 id 从您的 url 转换为数字,它也应该与 === 一起使用。要在找到商店数据后呈现您的商店数据,不应使用地图完成,因为您无法使用它访问对象键。你应该用 shop.nom 等渲染它。希望这会有所帮助。快乐编码。


推荐阅读