Reputation: 3750
I've found lots of similar problems, can't seem to sort my case
I have a component that won't re-render when data changes.
When MODE
changes, which is a string, the entity re-renders and updates.
When hotspot.description
changes, it won't update.
I can see the description has changed in the store, I can console log the changes all the way to this component.
However I just can't get this component to update when the description
changes in hotspot
.
Any clues!?
Connected
const mapStateToProps = (state) => {
return {
mode: state.admin.hotspot.mode,
hotspot: state.admin.hotspot.edit,
}
}
Pure
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
}
Here is where the description is edited
updateHotspotDescription(description){
let hotspot = this.state.hotspot
hotspot.description = description
hotspot.imageUpdateRequired = true
this.setState({hotspot : hotspot})
this.state.onUpdateHotspot(hotspot)
}
This is dispatched whenever text is changed, via a draft-js editor.
The state is updated with the changes, and another entity is aware of them.
Upvotes: 0
Views: 140
Reputation: 4464
You have to follow the Immutable pattern to update your value, even before passing it to redux (see updating nesting objects in the link).
So before sending hotspot.edit
to your reducer be sure to update the nested description
object following the immutable pattern like this :
updateHotspotDescription(description){
const hotspot = {
...this.state.hotspot,
description, // shorthand for description: description
imageUpdateRequired: true,
};
this.setState({ hotspot });
this.state.onUpdateHotspot(hotspot);
}
Upvotes: 2
Reputation: 4080
So you have to question yourself, are you sure your action
it's being actually taken?
Any non-case in the switch
statement will return the previous state, therefore It's normal that It won't re-render.
Some tips to follow to verify if your redux
state it's being updated:
constants
are imported correctly in your actions
and in your reducer
action
it's being properly taken by the reducerreducer
before your return it, so you can be sure that the next state is the correct oneFollow this steps and let me know if your problem persists
Upvotes: 0