Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React/redux prev状态随着下一个全州范围的变化而不断变化_Javascript_Reactjs_Redux_React Redux_State - Fatal编程技术网

Javascript React/redux prev状态随着下一个全州范围的变化而不断变化

Javascript React/redux prev状态随着下一个全州范围的变化而不断变化,javascript,reactjs,redux,react-redux,state,Javascript,Reactjs,Redux,React Redux,State,当有人评论时,我想更改图像的状态,以便将新的评论添加到屏幕上。状态确实会更改,但不会调用新渲染,因为旧状态会随新状态一起更改。我尝试使用调试器,似乎第40行是旧状态更改的地方。我非常困惑,因为我使用的是Object.freeze(),而且我只使用了我创建的newState变量,甚至没有触及旧的状态。谢谢 import { RECEIVE_ALL_IMAGES, RECEIVE_ONE_IMAGE, REMOVE_IMAGE, REMOVE_IMAGES } from '../ac

当有人评论时,我想更改图像的状态,以便将新的评论添加到屏幕上。状态确实会更改,但不会调用新渲染,因为旧状态会随新状态一起更改。我尝试使用调试器,似乎第40行是旧状态更改的地方。我非常困惑,因为我使用的是Object.freeze(),而且我只使用了我创建的newState变量,甚至没有触及旧的状态。谢谢

import {
  RECEIVE_ALL_IMAGES,
  RECEIVE_ONE_IMAGE,
  REMOVE_IMAGE,
  REMOVE_IMAGES
} from '../actions/image_actions';

import {
  RECEIVE_LIKE,
  REMOVE_LIKE
} from '../actions/like_actions';

import {
  RECEIVE_COMMENT,
  REMOVE_COMMENT
} from '../actions/comment_actions';

const imagesReducer = (oldState = {}, action) => {
  Object.freeze(oldState);
  let newState = Object.assign({}, oldState);

  switch(action.type){
    case RECEIVE_LIKE:
      newState[action.like.imageId].likerIds.push(action.like.userId);
      return newState;
    case REMOVE_LIKE:
      newState[action.like.imageId].likerIds = newState[action.like.imageId].likerIds.filter(id => id !== action.like.userId);
      return newState;
    case RECEIVE_ALL_IMAGES:
      return Object.assign({}, oldState, action.images);
    case RECEIVE_ONE_IMAGE:
      return Object.assign({}, oldState, {[action.image.id]: action.image});
    case REMOVE_IMAGE:
      delete newState[action.image.id];
      return newState;
    case REMOVE_IMAGES:
      return {};
    case RECEIVE_COMMENT:
      if (newState[action.comment.imageId].comments) {
        newState[action.comment.imageId].comments[action.comment.id] = action.comment;
      } else if (newState[action.comment.imageId]) {
        newState[action.comment.imageId].comments = {};
        newState[action.comment.imageId].comments[action.comment.id] = action.comment;
      }
      return newState
    case REMOVE_COMMENT:
      delete newState[action.comment.imageId].comments[action.comment.id]
      return newState
    default:
      return oldState;
  }
};

export default imagesReducer;

您只需冻结和复制第一层属性,然后再将层更改为更深一层,这些属性仍然是共享的。下面是一个代码段,它显示了正在发生的事情以及更改它的一种方法,但您可能希望了解如何使用一个库,以使这一点更容易得到正确的结果:

constoldstate={
id1:{注释:{cid1:'Comment1'}},
id2:{comments:{cid2:'Comment2'}}
};
document.getElementById(“step1”).innerHTML='oldState='+JSON.stringify(oldState);
对象。冻结(旧状态);
const newState=Object.assign({},oldState);
newState.id1.comments.cid3='Comment3';
document.getElementById(“step2”).innerHTML='oldState='+JSON.stringify(oldState)+'
newState='+JSON.stringify(newState); const newStateNoSideEffects={…oldState}; newStateNoSideEffects.id2={…newStateNoSideEffects.id2}; newStateNoSideEffects.id2.comments={…newStateNoSideEffects.id2.comments,cid4:'Comment4'}; document.getElementById(“step3”).innerHTML='oldState='+JSON.stringify(oldState)+'
newState='+JSON.stringify(newState)+'
newStateNoSideEffects='+JSON.stringify(newStateNoSideEffects)






您只复制了较浅的旧状态,但您正在对象中更深的位置变异值。冻结只适用于对象本身,而不是根对象属性值的嵌套对象。谢谢提示!我搜索了一个库,找到了loadash,现在使用merge而不是Object.assign!lodash merge仍将继续,我已经添加了一个用于此目的的库(不变性助手)的示例。