我有一个有9个减速器的商店。我只希望我的组件听取其中一个discoverSearch
。使用mapStateToProps
的简写版本,这是我的代码。但是,该组件仍在componentWillReceiveProps
中传递所有减速器。
组件
import React from 'react'
import { connect } from 'react-redux'
import { View, Text, Animated, Dimensions } from 'react-native'
const _ = require('lodash')
import colors from '../../Color'
import DiscoverSearchResultChannel from './DiscoverSearchResultChannel'
import DiscoverSearchResultEpisode from './DiscoverSearchResultEpisode'
const { height, width } = Dimensions.get('window')
class DiscoverSearchResultsContainer extends React.Component {
constructor() {
super()
this.generateResultsList = this.generateResultsList.bind(this)
}
generateResultsList(results, type) {
const components = []
for (let i = results.length - 1; i >= 0; i--) {
if (type === 'CHANNEL') {
const result =
(<DiscoverSearchResultChannel
entry={results[i]}
key={`dsearch-${results[i].id}`}
navigation={this.props.navigation}
/>)
components.push(result)
} else if (type === 'EPISODE') {
const result =
(<DiscoverSearchResultEpisode
entry={results[i]}
key={`dsearch-${results[i].id}`}
navigation={this.props.navigation}
/>)
components.push(result)
}
}
return components
}
render() {
const { episodes, channels } = this.props.discoverSearch.results
return (
<Animated.ScrollView
style={styles.shell}
contentContainerStyle={styles.innerContent}
>
<Text style={styles.divider}>Podcasts</Text>
{
_.isUndefined(channels) ? null : this.generateResultsList(channels, 'CHANNEL')
}
<Text style={styles.divider}>Episodes</Text>
{
_.isUndefined(episodes) ? null : this.generateResultsList(episodes, 'EPISODE')
}
</Animated.ScrollView>
)
}
}
export default connect(store => (
{ discoverSearch: store.discoverSearch },
dispatch => dispatch
))(DiscoverSearchResultsContainer)
商店
import { applyMiddleware, createStore } from 'redux'
import { createLogger } from 'redux-logger'
import thunk from 'redux-thunk'
import promise from 'redux-promise-middleware'
import combinedReducers from './reducers/CombineReducers'
const middleware = applyMiddleware(
thunk,
createLogger(),
promise()
)
export default createStore(combinedReducers, middleware)
DiscoverSearchReducer
const initialState = {
results: []
}
const DiscoverSearchReducer = (state = initialState, action) => {
let newState
switch (action.type) {
case 'DISCOVER_SEARCH_REQUEST_OUT':
// TODO
break
case 'DISCOVER_SEARCH_RETURN':
newState = {
...state,
results: action.payload
}
break
default:
return state
}
return newState
}
减速
export default combineReducers({
network: NetworkReducer,
audioPlayer: AudioPlayerReducer,
fileHandler: FileHandlerReducer,
currentTrack: CurrentTrackReducer,
trackQueue: TrackQueueReducer,
asyncStatus: AsyncStatusReducer,
makeClip: MakeClipReducer,
userProfile: UserProfileReducer,
scrollListener: ScrollListenReducer,
userClips: UserClipsReducer,
discoverSearch: DiscoverSearchReducer,
})
应用程序录入
class App extends React.Component {
componentWillMount() {
// TODO
// Initialize Firebase => get UID then...
store.dispatch(fetchUser('7713BNBNPODPIE'))
}
componentDidMount() {
TrackPlayer()
}
render() {
return (
<Provider store={store} >
<View style={{ flex: 1 }}>
<Navigation />
<BottomPlayer />
</View>
</Provider>
)
}
}
export default App
Redux的连接件对我来说有点新鲜,所以我可能会遗漏一些明显的东西?
编辑:
添加了App.js入口点
添加了完整的DiscoverSearchResultsContainer
组件减去styles
答案 0 :(得分:3)
错误在您的连接功能中:
export default connect(store => (
{ discoverSearch: store.discoverSearch },
dispatch => dispatch
))(DiscoverSearchResultsContainer)
你的括号错了,这相当于:
connect(store => {
// this does nothing
{ discoverSearch: store.discoverSearch };
return dispatch => dispatch;
})(...)
实际上与
相同connect(state => state)(...)
你可能想写的是:
connect(store = ({ discoverSearch: store.discoverSearch }),
dispatch => dispatch)(...)
编辑:删除不必要的调度
如评论所示,映射调度是没用的,你可以做到
const mapStateToProps = state => ({ discoverSearch: state.discoverSearch });
connect(mapStateProps)(Component);
答案 1 :(得分:2)
使用连接最简单的方法是将mapStateToProps
和mapDispatchToProps
分离到自己的函数中,以避免出现语法错误,如果你无论如何都要将dispatch作为第二个参数返回不使用它,因为如果要连接的第二个参数为空,则默认返回dispatch。
[mapDispatchToProps(dispatch, [ownProps]): dispatchProps] (Object or Function):
如果传递了一个对象,则假定其中的每个函数 成为Redux动作创作者。具有相同函数名的对象, 但是每个动作创建者都会被包裹在一个调度呼叫中,所以他们可以 直接调用,将合并到组件的道具中。如果传递了一个函数,它将作为第一个函数发送 参数。你可以归还一个以某种方式使用的对象 发送以您自己的方式绑定动作创建者。 (提示:你可以使用 来自Redux的
bindActionCreators()
助手。)如果您的
mapDispatchToProps
函数被声明为两个 参数,它将被调用作为第一个参数和 道具作为第二个参数传递给连接组件, 并且只要连接的组件收到新的,就会重新调用 道具。 (第二个参数通常称为ownProps by 约定。)如果您不提供自己的
mapDispatchToProps
功能或对象 完整的动作创建者,默认mapDispatchToProps
实现只是将调度注入组件的道具。
您可以使用
等连接状态const mapStateToProps = store => {
return { discoverSearch: store.discoverSearch }
}
export default connect(mapStateToProps)(DiscoverSearchResultsContainer)
使用连接时
export default connect(store => (
{ discoverSearch: store.discoverSearch },
dispatch => dispatch
))(DiscoverSearchResultsContainer)
您确实将()
放在了错误的位置,因为您想要返回{ discoverSearch: store.discoverSearch }
而不是{ discoverSearch: store.discoverSearch }, dispatch => dispatch
。它应该是
export default connect(store => (
{ discoverSearch: store.discoverSearch })
)(DiscoverSearchResultsContainer)
以上代码段与
相同export default connect(store => {
return { discoverSearch: store.discoverSearch }
}
)(DiscoverSearchResultsContainer)
这就是你所需要的。但是你必须采用第一种方法
答案 2 :(得分:0)
你的DiscoverSearchReducer
是否有可能为每次发送返回一个新对象,即使在无操作时也是如此?
function reduceSomething(state, action) {
if action.type == "forMe":
return {action.payload}
else
return {...state}
}
而不是:
return state
因为前者会为每个调度提供一个新对象,具有预期内容,但是connect将无法禁止将props传递给您的组件。
这是一个奇怪的,但它符合你的症状。