0
votes

I'm still trying to render data from sockets but something is wrong with my code I really don't know what. If I put json data diractly into store items are rendered good. But If data are received from the sockets there is some problem with map function inside List.js. I've also repository for it: github

APP

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

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

ListContainer

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 })
      )
    )
  }
});

Actions

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;
  }
});

List

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>
    )
  }
});

I got error:

Objects are not valid as a React child (found: object with keys {id, title, name, createdAt, updatedAt}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of List

If I receive one object in socket it works pretty good. But I wanted to render multiple objects from array... How can I do that ? Thanks for any help!

MAYBE SOLUTION It works with this code but is it good solution ?

handleAddItem: function(newItem) {

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

1 Answers

1
votes

There is at least one problem.

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>
    );
  }
}