0

在花了几个小时尝试将数据从一个组件传递到另一个组件的各种方法之后,我完全不知道为什么下面的代码不起作用。

目的:我只是想在单击“NavLink”按钮时将“courseID”(一个字符串)传递给应用程序的状态;使 Navlink 打开的组件能够通过状态读取此字符串。

根据 console.log 消息,似乎使用正确的 courseID 值触发了“selectedCourseAction.js”,但 selectedCourseReducer 始终显示初始值并且实际上并未更新。

CourseDetails.js

import React from 'react';
import { connect } from 'react-redux';
import { firestoreConnect } from 'react-redux-firebase';
import { compose } from 'redux';
import { NavLink } from 'react-router-dom'; //Use NavLink rather than Link to gain access to the "active" class when the link is pressed.
import { selectedCourseID } from '../../store/actions/selectedCourseActions'


const CourseDetails = (props) => {


    const { ChosenCourse, removeCourse} = props;


    (...)

        console.log(props.match.params.id); <--------- Displays the currently selected Course Id.

        return(

            <div>

               (...)
                 
               //On NavLink click below, the idea is to pass the "course Id" of this component (displayed in 'props.match.params.id') into the "createLecture" component which the NavLink is trying to open via the "selectedCourseID" function found in "selectedCourseActions.js"
           
      <NavLink onClick={ () => selectedCourseID(props.match.params.id)} to={'/createlecture'} 
      className='btn btn-floating custom-orange lighten-1'>New Lecture</NavLink>

               (...)

        )

}

const mapStateToProps = (state, ownProps) => {

    const courseId = ownProps.match.params.id;

    console.log(courseId);   <------------------ Displays the currently selected Course Id.

     (...)
    
  
    return {
        selectedCourseID: courseId,   <------------This appears to trigger the selectedCourseAction.js
        (...)
        
    }

}

const mapDispatchToProps = (dispatch) => {

 (...)

}




export default compose(connect(mapStateToProps, mapDispatchToProps), firestoreConnect([
    {   
        (...)

    }
    
])
)(CourseDetails)

selectedCourseActions.js _

export const selectedCourseID = (CourseId) => {

    console.log('Inside SelectedCourseActions.js: ' + CourseId); <------- This is triggered when the NavLink in the "CourseDetails.js" component is clicked and this displays the CourseId.
    return {

        type: 'UPDATE_SELECTED_COURSE_ID', <--------- This leads to selectedCourseReducer.js
        SelectedCourseID: CourseId          <--------- Intending to pass this SelectedCourseID value into the selectedCourseReducer.js, to save its value in the state of the application for later retrieval.

    }
    
};

selectedCourseReducer.js _


const initState = 'Initial State of SelectedCourseReducer'; <---- Just temporary string to indicate if the initialState of the reducer is ever changed.


const selectedCourseReducer = (state=initState, action) => {
    


    switch (action.type) {
        
        case 'UPDATE_SELECTED_COURSE_ID':
            console.log('Updating Selected Course ID inside selectedCourseReducer: ', action.selectedCourseID); <------- THIS IS NEVER REACHED.  The default below is always called.
            return action.selectedCourseID;  <------- Trying to return the updated selectedCourseID value onto the state of the application.

        default:
            console.log('Hit Default State inside selectedCourseReducer: ', action.selectedCourseID); <----- THIS IS ALWAYS REACHED when this reducer is called with the "action.selectedCourseID" of "undefined".
            return state;
           
    }
    
}


export default selectedCourseReducer

对于未来的观众,这里是解决方案(灵感来自 markerikson 的回应)

您需要将 selectedCourseID 引入“CourseDetails.js”组件的 mapDispatchToProps 中。(请参阅下面的一些步骤/代码)

导入 useDispatch()

import { useDispatch } from 'react-redux';

引入 selectedCourseID 和 dispatch = useDispatch();

(...) 

const { ChosenCourse, removeCourse, selectedCourseID} = props;
    const dispatch = useDispatch();

(...)

更改 NavLink 以引用调度

<NavLink onClick={ () => dispatch(selectedCourseID(props.match.params.id))} to={'/createlecture'} ... 

在 mapDispatchToProps 中添加调度

const mapDispatchToProps = (dispatch) => {

    return {
        (...) 
        selectedCourseID: (courseId) => dispatch(selectedCourseID(courseId)),
    }

}
export default compose(connect(mapStateToProps, mapDispatchToProps), firestoreConnect([
    {   
        (...)

    }
    
])
)(CourseDetails)
4

1 回答 1

1

因为您没有发送 action。您正在调用selectedCourseID动作创建者,但动作从未被传递给store.dispatch

 onClick={ () => selectedCourseID(props.match.params.id)}

您应该通过参数传递selectedCourseID动作创建者mapDispatch,理想情况下使用“对象速记”形式mapDispatch

const mapDispatch = {selectedCourseID};

// later
export default connect(mapState, mapDispatch)(MyComponent);

然后按props.selectedCourseID字面意思或通过解构访问它:

const { ChosenCourse, removeCourse, selectedCourseID } = props;

或者,考虑使用React-Redux hooks API而不是connect,我们现在通常推荐:

const CourseDetails = (props) => {
  const dispatch = useDispatch();

  // later

  return <NavLink onClick={ () => dispatch(selectedCourseID(props.match.params.id))} />
}
于 2020-07-23T17:19:46.967 回答