我有一个小小的反应应用程序,我正在玩,只是去了解图书馆.该应用程序只是一系列列表,从服务器填充.单击列表项时,该项的值将添加到应用级别的列表过滤器,然后将用于调用新数据以填
问题是我似乎无法使我的列表与app(父)中的新数据协调,即使在调用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包含新信息.我错过了什么?
没有任何理由在州内保存道具;而将道具作为事实来源的错误则少得多.它还简化了代码.但是对于实际问题; 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中,您将中止这些请求.