From 5840b6025e803775b63fd3e18ab7fba2ad463838 Mon Sep 17 00:00:00 2001 From: Abishek Das Date: Tue, 14 Jan 2025 20:51:44 +0530 Subject: [PATCH] Fix: Prevent state mutation in course wikis update logic - Replaced direct mutation of "props.course.wikis" using ".push()" with an immutable update by dispatching the updated state. - Moved the dispatch logic into "useEffect" to avoid React warnings about state updates during render. - Resolves Redux error: "A state mutation was detected between dispatches, in the path 'course.wikis.o' " --- .../components/course_creator/course_form.jsx | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/components/course_creator/course_form.jsx b/app/assets/javascripts/components/course_creator/course_form.jsx index c7230ec749..4fba63d553 100644 --- a/app/assets/javascripts/components/course_creator/course_form.jsx +++ b/app/assets/javascripts/components/course_creator/course_form.jsx @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; import { Link } from 'react-router-dom'; import TextAreaInput from '../common/text_area_input.jsx'; import CreatableInput from '../common/creatable_input.jsx'; @@ -12,6 +13,7 @@ import selectStyles from '../../styles/select'; import WikiSelect from '../common/wiki_select.jsx'; import AcademicSystem from '../common/academic_system.jsx'; import WIKI_OPTIONS from '../../utils/wiki_options'; +import { updateCourse } from '@actions/course_actions.js'; const CourseForm = (props) => { const handleWikiChange = (wiki) => { @@ -31,6 +33,15 @@ const CourseForm = (props) => { props.updateCourseProps({ wikis }); }; + const dispatch = useDispatch(); + + useEffect(() => { + if (props.course.wikis && !props.course.wikis.length) { + dispatch(updateCourse({ wikis: [{ language: 'en', project: 'wikipedia' }] })); + } + }, []); + + let term; let courseSubject; let expectedStudents; @@ -133,17 +144,11 @@ const CourseForm = (props) => { ); } - - let privacyCheckbox; let campaign; let home_wiki; let multi_wiki; - if (props.course.wikis && !props.course.wikis.length) { - props.course.wikis.push({ language: 'en', project: 'wikipedia' }); - } - if (props.defaultCourse !== 'ClassroomProgramCourse') { home_wiki = (
@@ -181,6 +186,7 @@ const CourseForm = (props) => { /> ); } + if (props.course.initial_campaign_title) { campaign = ( { /> ); } + let backCondition; + if (Features.wikiEd) { backCondition = props.previousWikiEd; } else { @@ -198,15 +206,15 @@ const CourseForm = (props) => { let backOrCancelButton; -// Displays "Back" button if the user has clonable courses or is on the P&E dashboard; otherwise shows "Cancel" link. -if (props.hasClonableCourses || props.defaultCourse !== 'ClassroomProgramCourse') { - backOrCancelButton = ( - - ); - } else { - backOrCancelButton = ( - {I18n.t('application.cancel')} - ); + // Displays "Back" button if the user has clonable courses or is on the P&E dashboard; otherwise shows "Cancel" link. + if (props.hasClonableCourses || props.defaultCourse !== 'ClassroomProgramCourse') { + backOrCancelButton = ( + + ); + } else { + backOrCancelButton = ( + {I18n.t('application.cancel')} + ); } return (