React JS:调用 setState 后组件未更新
Posted
技术标签:
【中文标题】React JS:调用 setState 后组件未更新【英文标题】:React JS: Component not updating, after calling setState 【发布时间】:2014-04-19 19:32:47 【问题描述】:我正在玩一个小型的 react 应用程序,去了解库的窍门吧。该应用程序只是从服务器填充的一系列列表。单击列表项时,该项的值将添加到应用级别的列表过滤器中,然后将用于调用新数据以填充列表。
问题在于,即使调用setState
,我似乎也无法让我的列表与来自应用程序(父级)的新数据相一致。这是我的代码(咖啡):
###
@jsx React.DOM
###
div, h1, h2, h4, ul, li, form, input, br, p, strong, span, a = React.DOM
SearchApp = React.createClass
handleTopItemClick: (filter) ->
facet = filter.field
filters = @state.filters
if filters.facets[facet] and filters.facets[facet].length > 0
filters.facets[facet].push filter.value
else
filters.facets[facet] = [filter.value]
strArr = []
_.each filters.facets, (valArr, field) ->
_.each valArr, (val) ->
strArr.push "+(#field:\"#val\")"
@setState
filters: filters
queryStr: strArr.join(' ').trim()
getInitialState: ->
filters:
facets:
queryStr: ''
render: ->
(div
id: 'content'
className: "search-wrap"
,
(h1 , "Search")
(div
id: 'widgets',
(TopList
title: 'Top Domains'
params:
query: @state.queryStr
field: 'domain'
onItemClick: @handleTopItemClick
)
(TopList
title: 'Top Senders'
params:
query: @state.queryStr
field: 'from'
onItemClick: @handleTopItemClick
)
(TopList
title: 'Top Recipient'
params:
query: @state.queryStr
field: 'recipient'
onItemClick: @handleTopItemClick
)
)
)
TopItem = React.createClass
getDefaultProps: ->
value: ''
count: 0
field: null
render: ->
(li ,
(a
onClick: @handleClick
className: 'top-item-filter'
title: @props.value
,
(strong , @props.value)
(span , @props.count)
)
)
handleClick: (event) ->
event.preventDefault()
@props.onItemClick @props.value
TopList = React.createClass
getInitialState: ->
data: []
params: @props.params
componentWillReceiveProps: (nextProps) ->
@setState params: nextProps.params
componentWillMount: ->
request.post("/facet").send(@state.params).end (results) =>
@setState data: JSON.parse(results.text)
render: ->
itemNodes = _.map @state.data, (item) =>
key = item.value
TopItem
value: item.value
count: item.count
key: key
onItemClick: @handleItemClick
(div className: 'widget top-item',
(h2 className: 'widget-header', "#@props.title")
(ul className: 'top-items-list', itemNodes)
)
handleItemClick: (value) ->
@props.onItemClick
value: value
field: @props.params.field
React.renderComponent SearchApp(null), document.getElementById("content")
列表在第一次时都呈现良好,按预期获取未过滤的数据。当我点击一个列表项时,SearchApp
接收到事件,并相应地更新自己的状态。 componentWillReceiveProps
在 TopList
类上被正确调用,但 setState
调用不会更新它们的状态,因此它们不会协调。我已验证 nextProps
包含新信息。我错过了什么?
【问题讨论】:
【参考方案1】:没有任何理由将道具保存在状态中;并且将道具作为真相的来源更不容易出错。它还稍微简化了代码。
不过,对于实际问题; componentWillMount 在这里只调用一次。如果要在传递新参数时重复 AJAX 请求;你可以这样做:
TopList = React.createClass
getInitialState: ->
data: []
getSearchResultsFromServer: (params) ->
request.post("/facet").send(params).end (results) =>
if @isMounted()
@setState data: JSON.parse(results.text)
componentWillReceiveProps: (nextProps) -> @getSearchResultsFromServer nextProps.params
componentDidMount: -> @getSearchResultsFromServer @props.params
render: ->
itemNodes = _.map @state.data, (item) =>
key = item.value
TopItem
value: item.value
count: item.count
key: key
onItemClick: @handleItemClick
(div className: 'widget top-item',
(h2 className: 'widget-header', "#@props.title")
(ul className: 'top-items-list', itemNodes)
)
handleItemClick: (value) ->
@props.onItemClick
value: value
field: @props.params.field
理想情况下,您的 ajax 库将支持中止请求;并在 componentWillUnmount 中中止这些请求。
【讨论】:
做到了。非常感谢!正如你所建议的,我还通过道具删除了状态设置。以上是关于React JS:调用 setState 后组件未更新的主要内容,如果未能解决你的问题,请参考以下文章
无法在 socket.io 回调 React.js 中调用 setState