即使我没有改变它的mapPropsToState,也会调用选择器

时间:2017-09-23 04:21:12

标签: reactjs redux react-redux

我有一个React应用程序可以做一些简单的录音。我有一个组件Recorder,它连接到我的redux商店,如下所示:

export default connect(
    state => ({ 
        recordings: state.recordings,
        recordingSelector: selectRecordingBufferWithID(this.recordingID) 
    }), 

    dispatch =>
        bindActionCreators({ 
                startNewRecordingAction, 
                stopNewRecordingAction 
            },
            dispatch
        )
)(SampleRecorder);

我遇到的问题是我的redux代码中的selectRecordingBufferWithID经常被解雇。我的reducer代码的一部分如下所示:

function samplesReducer(state = [], action) {
    switch (action.type) {
        case MORE_SAMPLES:
            return [...action.samples];
        default:
            return state
    }   
}

function recordingsReducer(state = [], action) {
    switch (action.type) {
        case NEW_RECORDING:
            return newRecording(state, action.recordingID);
        case STOP_RECORDING:
            return stopRecording(state, action.recordingID);
        default:
            return state

    }
}

const rootReducer = combineReducers({
    samplesReducer,
    recordingsReducer
})

const store = createStore(rootReducer);
export { store };

因此,虽然我希望仅在selectRecordingBufferWithID操作发生时才使用START/STOP_RECORDING,但每次调用MORE_SAMPLES时都会调用它。

我对react-redux的理解是选择器是mapStateToProps函数接受的connect函数的一部分。不知何故,connect导致我的组件渲染,并使用redux存储中的映射状态更新其props。每次发生这种情况时,也会调用selectRecordingBufferWithID选择器,这样我就可以对商店进行精确的getter。

总而言之,我recordingSelector的解雇频率超出了我的预期。我唯一的理论是,每次尝试减少state.recordings时,我的Reducer都会以某种方式改变state.samples的状态,这会使react-redux渲染我的组件并将其映射到state.recording。< / p>

但除此之外,我被困住了。

1 个答案:

答案 0 :(得分:1)

connect无法按照您的想法运作。它真正的作用是:

  1. 订阅商店。此订阅将在每个已发送的操作
  2. 之后触发
  3. 执行mapStateToProps,将初始道具集注入Sample Recorder组件。
  4. 当任何操作发送时,订阅会启动,并且connect会再次将您的mapStateToProps应用于新的全局状态。
  5. 如果您的选择器返回与之前相同的道具,则不会再次渲染SampleRecorder。
  6. 所以误解是你的选择器不应该被调用。但事实是connect需要调用你的选择器来决定何时重新渲染,何时不重新渲染。

    这个摘要是您的选择器应该是简单的,或使用reselect可记忆,以避免昂贵的计算。你没有向你显示选择器代码,所以我们无法从这里看出来。 :)