【问题标题】:Update React when Data in Object in Store has changed当 Store 中对象中的数据发生变化时更新 React
【发布时间】:2018-07-24 19:14:11
【问题描述】:

我发现了很多类似的问题,似乎无法对我的情况进行分类

我有一个组件在数据更改时不会重新渲染。

MODE 更改时,这是一个字符串,实体会重新渲染和更新。

hotspot.description 更改时,它不会更新。

我可以看到商店中的描述已更改,我可以通过控制台将更改一直记录到该组件。

但是,当descriptionhotspot 中发生变化时,我无法更新此组件。

有什么线索吗!?

已连接

const mapStateToProps = (state) => {
  return {
    mode: state.admin.hotspot.mode,
    hotspot: state.admin.hotspot.edit,
  }
}

纯的

export default class HotspotRenderer extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      hotspot:props.hotspot,
      mode:props.mode,
    }
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      hotspot : nextProps.hotspot,
      mode: nextProps.mode,
    })
  }

  render() {
    const {hotspot,mode} = this.state

    const isEditingText = hotspot && mode === HOTSPOT_EDIT_MODE.TEXT
    const html = hotspot != null ? ReactHtmlParser(draftToHtml(hotspot.description)) : null

    return (
      <div>
        {
          isEditingText &&
          <Container>
            <div className={`hotspot-renderer hotspot${hotspot.id} hotspot-text-default`}><div>{html}</div></div>
          </Container>
        }
      </div>
    )
  }
}

admin.state.hotspot

const initialState = {
  isDraggingNewHotspot: false,
  edit:null,
  mode:null,
}

export function hotspot(prevState=initialState, action) {
  switch(action.type) {
  case START_ADD_HOTSPOT:      return { ...prevState, isDraggingNewHotspot: true }
  case FINISH_ADD_HOTSPOT:     return { ...prevState, isDraggingNewHotspot: false }
  case ADD_HOTSPOT:            return { ...prevState,  mode: HOTSPOT_EDIT_MODE.DRAG}
  case EDIT_HOTSPOT:           return { ...prevState,  edit: action.hotspot}
  case FINISH_EDIT_HOTSPOT:    return { ...prevState,  edit: null}
  case EDIT_HOTSPOT_MODE:      return { ...prevState, mode: action.mode }
  case UPDATE_HOTSPOT:         return { ...prevState, edit : action.hotspot }
  case GO_TO_EDIT_SCENE:       return { ...prevState, edit :null,mode :null }
  case UPDATE_SCENE_HOTSPOT_SUCCESS: return { ...prevState, edit: processUpdatedHotspot(prevState.edit,action.payload) }
  default:                     return prevState
  }
}

function processUpdatedHotspot(prev,update){

  if(!prev)
    return null

  if(!prev.id)
    prev.id = update.id

  return prev
}

这里是编辑描述的地方

  updateHotspotDescription(description){
    let hotspot = this.state.hotspot
    hotspot.description = description
    hotspot.imageUpdateRequired = true
    this.setState({hotspot : hotspot})
    this.state.onUpdateHotspot(hotspot)
  }

每当文本发生更改时,都会通过 Draft-js 编辑器发送此消息。

状态随着更改而更新,并且另一个实体知道它们。

【问题讨论】:

  • 在更新 hotspot 值时,您可能正在改变嵌套对象,您能显示您的调度操作吗?
  • 你能显示state.admin.hotspot的结构吗
  • 我认为@Dyo 是对的——processUpdatedHotspot 正在变异prev,这是状态的一部分。
  • 谢谢,我尝试删除它.. 但 ti 没有任何区别。会再看一遍。编辑 - 是的。没有区别。
  • 很好奇为什么组件有状态。它似乎完全反映了道具。你能把 componentWillReceiveProps 和构造函数去掉吗?

标签: reactjs redux react-redux


【解决方案1】:

您必须按照 Immutable pattern 更新您的值,甚至在将其传递给 redux 之前(请参阅链接中的更新嵌套对象)。

因此,在将hotspot.edit 发送到您的reducer 之前,请务必按照这样的不可变模式更新嵌套的description 对象:

updateHotspotDescription(description){
    const hotspot = { 
        ...this.state.hotspot,
        description, // shorthand for description: description
        imageUpdateRequired: true,
    };
    this.setState({ hotspot });
    this.state.onUpdateHotspot(hotspot);
}

【讨论】:

  • 优秀的答案!太感谢了。效果很好,我会进一步阅读。
【解决方案2】:

所以你必须自问,你确定你的action 真的被占用了吗?

switch 语句中的任何非大小写都会返回之前的状态,因此不会重新渲染是正常的。

验证您的 redux 是否正在更新的一些提示:

  • 确保您的constants 正确导入到您的actionsreducer
  • 确保触发的action 被reducer 正确接收
  • 在您返回之前将下一个状态记录在您的reducer 中,这样您就可以确定下一个状态是正确的

按照这些步骤,如果您的问题仍然存在,请告诉我

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 2013-07-03
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多