为什么我的reactJs没有重新渲染

时间:2014-06-30 00:05:48

标签: javascript reactjs

我真的厌倦了模型绑定,并试图开始使用React,因为我非常喜欢整个无状态的想法。我完成了教程,看起来很简单。

然而,在我自己的应用程序中,我很困惑为什么我的组件不会在状态更改时重新呈现。这是我在coffeescript中的全部应用程序(来自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 '+@state.class, style: (left: @state.position)), ""+@state.position

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

我们在3个车道中基本上有3个div。当你点击每个泳道时,每个div应该在它上面移动(调整左内联样式)。

我定义了一个advance方法,它修改我的racers对象,然后在我的视图根上调用setState。而且这个位置......并没有改变。

我知道我在正确的轨道上,如果不是改变我移除的位置或添加一个它应该工作的赛车 - 但它不会重新渲染一个级别。我做错了什么?

2 个答案:

答案 0 :(得分:4)

当您在根setState组件上调用RaceTrack时,它会触发重绘并通过道具将新的赛车位置传递给Racer组件。但是,这些新位置最终会被忽略:首次创建游戏时,您将其初始位置存储在其内部状态,并且您将基于此内部状态呈现Racer组件,该状态永远不会更新。

一个快速解决方法是根据道具而不是状态更改要渲染的赛车。

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

Racer = React.createClass 
    render: ->
        R.div (className: 'racer '+@props.class, style: (left: @props.position)), ""+@props.position

总结一下,我认为这里最重要的一点是,在使用React时,你应该尽量避免冗余状态。让根组件成为唯一一个具有状态并且使用道具的东西,这是一种常见的模式。

答案 1 :(得分:0)

我认为确保重新绘制组件的最简单方法是更改​​键属性。对元素键的任何更改都将强制它完全重绘。如果你使键值取决于道具,那也将解决问题。