Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't my reactJs re-rendering

I'm really tired of model-binding and am trying to get started with React as I really like the whole stateless idea. I went through the tutorial and it seems straightforward enough.

However, in my own app I am confused why my component isn't re-rendering on state change. Here is the entirety of my app in coffeescript (_ helpers from lodash).

mapObject = _.compose _.object, _.map

racers = mapObject ['red', 'blue', 'green'], (name) -> 
    [name, (key: name, class: name, position: 0)]

advance = (character) ->
    racers[character].position += 5;
    console.log character, "position is", racers[character].position
    view.setState racers: racers

R = React.DOM

Racer = React.createClass 
    getInitialState: -> @props
    render: ->
        R.div (className: 'racer '[email protected], style: (left: @state.position)), ""[email protected]

Racelane = React.createClass render: -> 
    R.li (onClick: _.partial advance, @props.key), Racer @props

Racetrack = React.createClass 
    getInitialState: -> @props
    render: ->
        R.ul (className: 'lanes'), _.map @state.racers, Racelane

view = React.renderComponent (Racetrack racers: racers), (document.querySelector '#racetrack')

Here it is live

we basically have 3 divs in 3 lanes. As you click on each lane each div is supposed to move across it (the left inline style is adjusted).

I define an advance method that modifies my racers object and then calls setState on my view root. And the position...does not change.

I know I'm on the right track, if instead of changing the position I remove or add a racer it works as it should - but it doesn't re-render one level down. What am I doing wrong?

like image 865
George Mauer Avatar asked Jul 01 '26 23:07

George Mauer


1 Answers

When you call setState on the root RaceTrack component it will trigger a redraw and pass the new racer positions to the Racer components via props. However, these new positions end up being ignored: When the racers are first created you are storing their initial position in their internal state and you are rendering the Racer components based on this internal state, which never gets updated.

One quick fix is to change the racers to render based on their props instead of state.

http://jsbin.com/bilejeyu/1/edit

Racer = React.createClass 
    render: ->
        R.div (className: 'racer '[email protected], style: (left: @props.position)), ""[email protected]

Wrapping up, I think the biggest lesson here is that when working with React, you should try to avoid redundant state. Having the root component be the only one with state and use props for everything one is a common pattern.

like image 170
hugomg Avatar answered Jul 04 '26 13:07

hugomg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!