【问题标题】:Redux state is not getting initialized to initial stateRedux 状态未初始化为初始状态
【发布时间】:2018-12-18 16:16:18
【问题描述】:

我是react-redux 的新手。在这里,我有一个减速器,就像,

const initialState = {
    Low: [
        {
            id: 0,
            technologyId: 0,
            technology: '',
            type: '',
            count: '',
            allowded: 6,
            level: 'EASY'
        }
    ],
    Medium: [
        {
            id: 0,
            technologyId: 0,
            technology: '',
            type: '',
            count: '',
            allowded: 7,
            level: 'MEDIUM'
        }
    ],
    High: [
        {
            id: 0,
            technologyId: 0,
            technology: '',
            type: '',
            count: '',
            allowded: 7,
            level: 'TOUGH'
        }
    ]
}

export default function QuizData(state = initialState, action) { 
   switch (action.type) {
        case QUIZ_DATA:
        return {
            ...state,
            [action.data.type]: [...action.data.tobeData],
            error: false,
        }
    case ADD_NEW:
        return {
            ...state,
            [action.data.addtype]: action.data.addData,
            error: false,
        }
    case REMOVE_TECH:
        return {
            ...state,
            [action.data.removeType]: action.data.newArr,
            error: false,
        }
        case RESET_QUIZ:
            return {
                ...initialState,
                error: false,
            }

 }

现在,点击按钮,我正在调用一个将数据重置为初始状态的操作。

this.props.resetQuiz();

这是

export function resetQuiz() {
  return {
    type: RESET_QUIZ
  }
}

我在哪里使用它

让 newData = { ...this.props.data };同时在组件中使用它来做一些操作。

现在发生的情况是在执行一些操作后,初始状态数据会随着一些新值发生变化,..

但是,在单击按钮时,我想将其设置为 initialState。

所以,当我尝试那个时候,initialState 也得到了相同的值。所以,它没有重置。

我在组件中使用它,

data: state.QuizData // In statetoprops.

let criterias = [{
      type: 'Low',
      noc: 6,
      id: 1,
      data: this.props.data["Low"]
    }, {
      type: 'Medium',
      noc: 7,
      id: 2,
      data: this.props.data["Medium"]

    },
    {
      type: 'High',
      noc: 7,
      id: 3,
      data: this.props.data["High"]
    }]

在像这样的组件中使用动作时,

createQuestionBankQuiz = () => {
    this.props.resetQuiz();
    history.push({
      pathname: "/quiz-setup/" + `${this.props.jdId}`
    });
  };



export default connect(mapStateToProps, { fetchListOfQuiz, updateQuestionViewMode, enableJob, resetQuiz })(LandingScreen);

我更新的方式是

onChange(event, tobeupdated, id, type, noc, data) {
    let newData = { ...this.props.data };
    let errorState;
    let isDuplicate;
    let addedRow;
    if (newData) {
      let data = newData[type].map((object, index) => {
        if (object.id === id) {
          object[tobeupdated] = event.target.value;
          const tobeData = newData[type];
          this.props.updateLowLevel({ tobeData, type }).then(() => {
            let criteria_filled = this.disableAddbutton({ ...this.props.data }, type);
            addedRow = `new${type}RowAdded`;
            this.setState({
              [addedRow]: criteria_filled ? true : false
            })
            const tobechecked = newData[type].filter(item => item.id === id);
            isDuplicate = this.checkPreviousSelected(newData, type, tobechecked[0].technology, tobechecked[0].type);
            if (isDuplicate) {
              toastr.error("Duplicate criteria. Please change it.");
              object["technology"] = '';
              object["type"] = '';
              const tobeData = newData[type];
              this.props.updateLowLevel({ tobeData, type });
            }
          });
        }
      });
      errorState = `show${type}Error`;
      if (tobeupdated !== "count") {
        this.getSelectionQuestionsNumber(type, id, noc);
      }
      let validateData = this.validate(type, noc);
      this.setState({
        [errorState]: validateData
      })
    }
  }

我做错了什么?

【问题讨论】:

  • 如果您想重置为 return initialState,为什么不能这样做? IE。 case RESET_QUIZ: return initialState;
  • 我也试过了。
  • 显然您正在将测验数据设置在其他地方。如果您在减速器中返回 initialState,则您的状态不会重置为 initialState。你是如何调度动作的?
  • 你的代码返回一个新的状态而不是重置initialState。所以试试Object.assign(initialState,{a:somevalue})这样的代码。
  • @lx1412 这违背了react-redux的原则。

标签: javascript reactjs redux react-redux


【解决方案1】:

我认为你的动作调度错了

export function resetQuiz() {
  return dispatch => {
    dispatch({
      type: RESET_QUIZ
    })
  }
}

我认为如果你在 reducer 中尝试这个会更好

export default function QuizData(state = initialState, action) {
  switch (action.type) {
    case RESET_QUIZ:
      return Object.assign({}, initialState, {error: false})

    default:
      return state;
  }
}

【讨论】:

  • 我刚刚尝试过,但它也给了我相同的值。
  • @ganeshkaspate 请用我编辑的return Object.assign({}, initialState, {error: false}) 重试。
  • 我刚刚更新了我在同一个减速器中使用其他案例的方式,
  • @ganeshkaspate 我认为您在调度操作中错了。请尝试我编辑的操作。
  • 很可能是动作的调度方式确实存在问题,很好的捕捉
【解决方案2】:

你只需要在reducer中返回初始值,例如:

export default function QuizData(state = initialState, action) {
  switch (action.type) {
    case RESET_QUIZ:
      return initialState

    default:
      return state;
  }
}

【讨论】:

    【解决方案3】:

    您忘记在减速器中返回 state 以执行 default 操作:

    export default function QuizData(state = initialState, action) { 
       switch (action.type) {
            case QUIZ_DATA:
            return {
                ...state,
                [action.data.type]: [...action.data.tobeData],
                error: false,
            }
        case ADD_NEW:
            return {
                ...state,
                [action.data.addtype]: action.data.addData,
                error: false,
            }
        case REMOVE_TECH:
            return {
                ...state,
                [action.data.removeType]: action.data.newArr,
                error: false,
            }
            case RESET_QUIZ:
                return {
                    ...initialState,
                    error: false,
                }
    
       return state; // you forgot this
     }
    

    redux 在 store 初始化时发出某种 init 操作,因此您需要在减速器中返回给定的 state 以用于其他操作而不是您自己定义的操作。

    【讨论】:

    • 我有默认的:
    • 好吧,我误解了你的问题,你能告诉我们你的connect组件的代码吗?我想你可能忘了真正派发这个动作。
    • 导出默认连接(mapStateToProps, { fetchListOfQuiz, updateQuestionViewMode, enableJob, resetQuiz })(LandingScreen);
    • @ganeshkaspate 顺便说一句,您仍然无法在减速器中默认返回初始状态
    • 不在您发布的代码中,仍然缺少 QuizData 减速器的“默认情况”
    【解决方案4】:

    可能是您没有在其他操作中进行深度复制。

    能否为其他动作添加reducer的代码?

    编辑: 您的问题的快速解决方案是更改减速器,如下所示:

    export default function QuizData(state = JSON.parse(JSON.stringify(initialState)), action) { 
      ....
     }
    

    注意:JSON.parse(JSON.stringify(initialState)) 适用于您的情况,但不适用于所有情况,也不是一个好的解决方案。你必须为此编写深拷贝逻辑。

    正确/正确的解决方案

    您必须修改您的组件逻辑以不直接修改存储数据并通过其他操作对其进行更新。

    【讨论】:

    • 我更新的方式是,我也加了。
    • 在您将 QuizData 添加到条件的组件中,实际上将引用 initialState 内部对象。所以对内部对象的任何修改都会导致实际的 initialState 对象修改。 (...state) 将仅复制第一级属性。您可以在更新“标准”数据的地方添加组件代码吗?
    • 对象[待更新] = event.target.value;在这里您正在更新现有对象,而不是您可以执行 {...object, [tobeupdated]: event.target.value}
    • 这里我做 let newData = { ...this.props.data };
    • 能否请您将其添加到答案中以便我检查
    猜你喜欢
    • 2019-05-08
    • 2023-01-27
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    • 2018-08-22
    相关资源
    最近更新 更多