【问题标题】:The prop `store.subscribe` is marked as required道具 `store.subscribe` 被标记为必需
【发布时间】:2018-03-22 02:50:59
【问题描述】:

我正在尝试将一个组件连接到 redux 商店,但正在接收:

Warning: Failed prop type: The prop 'store.subscribe' is marked as required inConnect(StoreLocation), but its value is 'undefined'.

我在这个项目中使用 redux 已经有一段时间没有问题了,但是这个组件由于某种原因出错了,我现在不知道为什么:(

商店在DeliverySection.js 内填充了一系列商店(实体店地址、电话号码等用于送货选择)。

然后每个StoreLocation.js 组件将允许用户查看它的信息、选择它等。它现在只是简单的,因为即使在这个基本点上我也看到了错误。如果我用export default StoreLocation 切换export default connect()(StoreLocation) 语句,它可以正常工作。

有什么想法吗?

DeliverySection.js

import React, { Component } from 'react'
import { connect } from 'react-redux'

// Components
import Loader from '../../utils/Loader'
import StoreLocation from './StoreLocation'

// Stote
import { getAllStores } from '../../../store/actions/storeLocation'
import { REACT_APP_SITE_KEY } from '../../../shared/vars'

// CSS
import '../../../css/delivery.css'

class DeliverySection extends Component {
    componentDidMount(){
        this.props.getAllStores(REACT_APP_SITE_KEY);
    }

    render() {
        const { stores, isLoading } = this.props

        return (
            <div>
                <div className="delivery-heading">
                    <h2>Choose a store near you:</h2>
                    <button className="btn btn--red btn--heading" name="ship-to-address">Ship To An Address</button>
                </div>

                <div>
                    {isLoading ? (
                        <Loader />
                    ) : (
                        !isLoading && !!stores ? (
                            stores.map((store, i) => <StoreLocation key={i} store={store} />)
                        ) : (
                            <div>
                                There are no store locations to deliver to.<br />
                                Ship to an address!
                            </div>
                        )
                    )}
                </div>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        stores: state.storeLocation.stores,
        isLoading: state.storeLocation.isLoading
    }
}

export default connect(mapStateToProps, { getAllStores })(DeliverySection)

StoreLocation.js

import React, { Component } from 'react'
import { connect } from 'react-redux'

import { setDelivery } from '../../../store/actions/checkout'

class StoreLocation extends Component {
    render() {
        const { store } = this.props

        return (
            <div className="store-location">
                <div className="store-row">
                    <div className="store-col"><div className="store-title">{store.title}</div></div>
                    <div className="store-col">
                        {store.address}
                        {store.formatted_location &&
                            <div>{store.formatted_location}</div>
                        }
                    </div>
                    <div className="store-col">
                        <button className="btn select-store" onClick={() => this.props.setDelivery(store)}>Ship to this store<span className="icon-checkmark"></span></button>
                    </div>
                </div>
                <div className="store-row">
                    <div className="store-col">
                        <div className="ajax-message" data-hbs-id="postal-{id}"></div>
                        <input type="hidden" id={`postal-${store.id}`} value={store.postal} />
                        <div className="see-map"><span className="icon-location"></span>See on map</div>
                    </div>
                    <div className="store-col">{store.description}</div>
                    <div className="store-col"></div>
                </div>
                {store.phone &&
                    <div className="store-row">
                        <div className="store-col"></div>
                        <div className="store-col">{store.phone}</div>
                        <div className="store-col"></div>
                    </div>
                }
            </div>
        )
    }
}

export default connect(null, { setDelivery })(StoreLocation)
// export default StoreLocation

【问题讨论】:

  • 你缺少一个 connect 函数的参数,它是一个接收状态并返回一个对象以将其作为 props 传递给组件的函数,通常称为 mapStateToProps
  • @Jalissa 连接函数的参数是可选的。请查看github.com/reactjs/react-redux/blob/master/docs/…
  • 我错了,你是对的@palsrealm!谢谢!

标签: javascript reactjs redux


【解决方案1】:

这是因为您使用 store 作为道具名称。您正在覆盖通过 HOC 的 prop react-redux。由于您传递给 store 的对象没有 subscribe 方法,因此您会收到此错误。

如果你改变你的道具的名字,你会恢复良好的状态。

【讨论】:

  • 是的!现在很明显哈哈谢谢你在我问了这么久之后回答这个问题:)
【解决方案2】:

在快速谷歌后,我发现了这篇文章here。 该问题与您的问题相似,是基于商店的导出方式。看看那个,看看是否能让你朝着正确的方向前进。如果没有看到您的商店导出代码,我无法发表评论。

根据个人喜好,我会使用“商店”以外的其他内容作为商店地图中每个实例的变量。由于您使用的是 Redux,因此无论您指的是 Redux 存储还是存储对象的实例,都会在语义上产生混淆。

我认为让 StoreLocation 处理交付设置很好。我非常喜欢将事物分解成更小的组件。

最后,只是因为我碰巧注意到了,你在 DeliverySection 中有一个拼写错误。第 8 行读取 //Stote。我猜你的意思是//Store

【讨论】:

  • 如果您只想将dispatch 注入到您的道具中,您可以不带参数调用connect()。请查看github.com/reactjs/react-redux/blob/master/docs/…
  • 抱歉@palsrealm,我在文档中读错了,刚刚更新了我的评论。
  • 我已经根据我对 redux 商店的意图编辑了这个问题。我认为 StoreLocation 组件应该自己处理所选交付项目的设置,而不是父组件。也许我错了。
  • @Gurnzbot 我已根据您对原始帖子的编辑更新了我的评论。
【解决方案3】:

提前道歉,因为我认为这应该放在评论部分,但是您粘贴的代码看起来还不错。您说断开 StoreLocation 组件可以解决问题。您是否有理由要连接该组件?您没有将任何状态映射到道具或在该组件中使用调度。

否则,请确保您使用所需的 reducer 正确初始化存储,并检查您使用的模块是否正确导入 - 尤其是您传递给连接函数 (getAllStores) 的模块。

【讨论】:

  • 我计划使用一个名为 setDelivery 的调度函数,它将 StoreLocation 设置为活动项目,但我决定从问题中删除任何我能做的事情,以使其尽可能简单.如果我将最后一行更改为export default StoreLocationgetAllStores 会按预期填充。我不知道为什么连接 StoreLocation 组件会引发错误。
猜你喜欢
  • 2018-09-22
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2021-12-26
  • 2020-01-26
  • 2021-09-28
  • 1970-01-01
  • 2018-10-18
相关资源
最近更新 更多