【问题标题】:React-Flux not showing array of objects from socketsReact-Flux 未显示来自套接字的对象数组
【发布时间】:2016-02-27 05:06:49
【问题描述】:

我仍在尝试从套接字呈现数据,但我的代码出了点问题,我真的不知道是什么。如果我将 json 数据直接放入商店项目中,效果会很好。但是如果从套接字接收到数据,则 List.js 中的 map 函数存在一些问题。 我也有它的存储库:github

应用程序

var App = React.createClass({
  render: function() {
    return (
      <div className="container">
        <div className="row">
          <ListContainer />
        </div>
      </div>
    )
  }
});

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

列表容器

var ListContainer = React.createClass({
  propTypes: {
    list: React.PropTypes.array,
  },
  getInitialState: function() {
    return {
      list: todoStore.getList()
    }
  },
    componentWillMount: function componentWillMount() {
        this.socket = io('www.example.com');
        this.socket.on('tables', this.handleAddItem);
    },
  componentDidMount: function() {
    todoStore.addChangeListener(this._onChange);
  },
  componentWillUnmount: function() {
    todoStore.removeChangeListener(this._onChange);
  },
  handleAddItem: function(newItem) {
      console.log("handleAddItem called");
    todoActions.addItem(newItem);
  },
  handleRemoveItem: function(index) {
    todoActions.removeItem(index);
  },
  _onChange: function() {
    this.setState({
      list: todoStore.getList()
    });
  },
  render: function() {
    return (
      React.createElement(
        "div",
        { className: "col-sm-6 col-md-offset-3" },
        React.createElement(List, { items: this.state.list, remove: this.handleRemoveItem })
      )
    )
  }
});

操作

var todoActions = {
  addItem: function(item) {
      console.log("Action called");
    AppDispatcher.handleAction({
      actionType: appConstants.ADD_ITEM,
      data: item
    });
  },
  removeItem: function(index) {
    AppDispatcher.handleAction({
      actionType: appConstants.REMOVE_ITEM,
      data: index
    });
  }
};

AppDispatcher

AppDispatcher.handleAction = function(action) {
  this.dispatch({
    source: 'VIEW_ACTION',
    action: action
  });
};

todoStore

var CHANGE_EVENT = 'change';

var _store = {
  list: []
};
var addItem = function(item) {
   console.log("push to store called");
  _store.list.push(item);
};
var removeItem = function(index) {
  _store.list.splice(index, 1);
};
var todoStore = objectAssign({}, EventEmitter.prototype, {
  addChangeListener: function(cb) {
    this.on(CHANGE_EVENT, cb);
  },
  removeChangeListener: function(cb) {
    this.removeListener(CHANGE_EVENT, cb);
  },
  getList: function() {
    return _store.list;
  }
});
AppDispatcher.register(function(payload) {
  var action = payload.action;
  switch(action.actionType) {
    case appConstants.ADD_ITEM:
      addItem(action.data);
      console.log("Dispacher called");
      todoStore.emit(CHANGE_EVENT);
      break;
    case appConstants.REMOVE_ITEM:
      removeItem(action.data);
      todoStore.emit(CHANGE_EVENT);
      break;
    default:
      return true;
  }
});

列表

var List = React.createClass({
  render: function() {
    var listItems = this.props.items.map(function(item, index) {
      return (
        <li key={index} className="list-group-item">
          <span className="glyphicon glyphicon-remove">
          </span>
          <span>
           {console.log(item.title)} 
          </span>
        </li>
      )
    }.bind(this));
    return (
      <ul>
        {listItems}
      </ul>
    )
  }
});

我收到错误:

对象作为 React 子对象无效(发现:对象带有键 {id、title、name、createdAt、updatedAt})。如果您打算渲染一组子项,请改用数组或使用 React 附加组件中的 createFragment(object) 包装对象。查看List的渲染方法

如果我在套接字中收到一个对象,它的效果会很好。但我想从数组中渲染多个对象......我该怎么做? 感谢您的帮助!

可能的解决方案 它适用于这段代码,但它是一个好的解决方案吗?

handleAddItem: function(newItem) {

  for(var i = 0; i < newItems.length; i++){
      todoActions.addItem(newItem[i]);
  }
},

【问题讨论】:

    标签: javascript socket.io reactjs reactjs-flux


    【解决方案1】:

    至少有一个问题。

    var List = React.createClass({
      render: function() {
        var listItems = this.props.items.map(function(item, index) {
          console.log(item);
          return (
            <li key={index} className="list-group-item">
              <span className="glyphicon glyphicon-remove">
              </span>
              <span>
               {item.name}{item.title}
              </span>
            </li>
          )
        }, this);
        return (
          <ul>
            {listItems}
          </ul>
        )
      }
    });

    [
      {
        "comment": "",
        "snip": "<i class=\"fa fa-camera-retro\"></i>"
      },
      {
        "comment": "button with image lines up wrong without this",
        "snip": "* { outline: none; }\n"
      },
      {
        "comment": "",
        "snip": ".TreeButtonImg {\n\tpadding: 0px;\n\tvertical-align: top;\n}"
      }
    ]

    class SnipListItem extends React.Component {
      constructor(props) { super(); }
      snipClickHandler = (buttonid) => { Actions.selectSnipItem(this.props.snippet, buttonid); }
      render() {
        let SnipSpanSty = {width: 'calc(70% - 142px)'};
        SnipSpanSty.color = (this.props.index === this.props.selectedKey) ? '#b58900' : '#afac87';
        return (
          <div id='SnipDivSty' onclick={this.snipClickHandler} className="FlexBox" style={SnipDivSty}>
            <div id='SelectSnipDivSty' style={SelectSnipDivSty}>
              <JButton btn={selectSnipBtn} parentClickHandler={this.snipClickHandler} />
            </div>
            <span id='SnipSpanSty' style={SnipSpanSty}>{this.props.snippet.snip}</span>
            <JButton btn={SnipBtn} parentClickHandler={this.snipClickHandler} />
          </div>
        );
      }
    }
    
    let _snipDataMap = function(snip, index) {
      return (
        <li id='SnipsDivLiSty' key={index} style={SnipsDivLiSty}>
          <SnipListItem snippet={snip} index={index} selectedKey={this.props.selectedKey} />
        </li>
      );
    }
    
    export default class SnipsView extends React.Component {
      render() {
        let list = this.props.data.map(_snipDataMap, this)
        return (
          <div id='SnipsDivSty' style={SnipsDivSty}>
            <ul id='SnipsDivUlSty' style={SnipsDivUlSty}>
              {list}
            </ul>
          </div>
        );
      }
    }

    【讨论】:

    • 非常感谢。它有效,但前提是我在套接字中有一个对象,但如果我使用对象数组,它不会。你知道怎么解决吗?
    • 唯一想到的是对象数组不知何故不是预期的格式。
    • 应该看起来像 [{name: 'one', title: 'onet'},{name: 'two', title: 'twot'}]
    • 是的,就像我已经拥有的一样……奇怪。也许我会回到backbonejs而不是:D ...如果我喜欢 todoActions.addItem(newItems[0]);它运行良好。但是只有一个对象可以确定...
    • 我添加了一个来自工作应用程序的示例。整件事都在github.com/calitek/Clippets
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    相关资源
    最近更新 更多