简体   繁体   中英

react add new row with the new incoming data

I have been trying this for a long time and it's driving me crazy. I have an app that receives orders (data) from sockets using socket io. I get the data and update the state in my app.js I have my app. js like this

import React, { Component } from 'react';
import './App.scss';
import { subscribeToTimer } from './api';
import Board from './components/Board';
import Stream from './components/orderStream';

class App extends Component {
  constructor(props) {
    super(props);
    subscribeToTimer((err, Order) => this.setState({ 
      Order 
    }));
  }
  state = {
    Order: 'no orders yet'
  };
  render() {
    console.log('STATE',this.state)
    return (
      <div className="App">
        <Stream
          OrderName = {this.state.Order.name}
          OrderEvent = {this.state.Order.event_name}
        />
        <Board 
         Order = {this.state.Order}
        />

      </div>  
    );
  }
}

export default App;

now, in my board I would like it to create a new row (card) every time the new data comes in. All i managed it to do is to display the row but re render it with the new data. I would like my table to be populated as the orders come in.

import React, { Component } from 'react'
import Card from '../components/Card'


class Board extends Component {


    constructor(props){
      super(props);
      this.renderTableRows= this.renderTableRows.bind(this);

      this.state = {
      }

    }

    renderTableRows(order){
      return(
        <Card
          ID = {order.id}
          Name ={order.name}
          Status ={order.event_name}
          Time = {order.sent_at_second}
          Destination ={order.destination}
        />
      );
    }

    render() {
        return (
        <div className="main-board flex-grid">
          <div id='resp-table'>
            <div id='resp-table-header'>
              <div className='table-header-cell order-ID'>
                Order ID
              </div>
              <div className='table-header-cell order-name'>
                Order Name
              </div>
              <div className='table-header-cell order-status'>
                Status
              </div>
              <div className='table-header-cell order-time'>
                Time
              </div>
              <div className='table-header-cell order-destination'>
                Destination
              </div>
            </div>
            <div id='resp-table-body'>
              {this.renderTableRows(this.props.Order)}
            </div>
          </div>
        </div>
        )
    };
}

export default Board;

this is the card component

import React, { Component } from 'react'


class Card extends Component{

  constructor(props){
    super(props);

  }

  render() {
    // console.log("this",this.props);
      return <div className="resp-table-row">
        <div className='table-body-cell'>
            {this.props.ID}
          </div>
          <div className='table-body-cell'>
            {this.props.Name}
          </div>
          <div className='table-body-cell'>
            {this.props.Status}
          </div>
          <div className='table-body-cell'>
           {this.props.Time}
          </div>
          <div className='table-body-cell'>
            {this.props.Destination}
          </div>
      </div>
    }
}

export default Card;

can anyone offer some insight please?

React creates the view from the modal (the data). In your case you wish the view to include all received orders. To do so, you need to save the orders in an array in the state (in the App component), and supply them to the component that renders the view ( Board ). The needs Board needs to iterate the array, and generate a list of Card components.

The App component should store all received orders in an array:

class App extends Component {
  constructor(props) {
    super(props);
    subscribeToTimer((err, Order) => this.setState(state => ({ 
      Order: [...state.Order, order] // add the Order to the previous state.Order
    })));
  }
  state = {
    Order: [] // init order with an empty array
  };
  render() {
    const { Order } = this.state;
    const { name, event_name } = Order[order.length - 1] || {}; // get the names from the laster order - or undefined if none
    return (
      <div className="App">
        <Stream
          OrderName = {name}
          OrderEvent = {event_name}
        />
        <Board 
         Order = {this.state.Order}
        />

      </div>  
    );
  }
}

And the Board component should render the entire array of table boards whenever one is added:

renderTableRows(order){
  return order.map(order => (
    <Card
      key = {order.id}
      ID = {order.id}
      Name ={order.name}
      Status ={order.event_name}
      Time = {order.sent_at_second}
      Destination ={order.destination}
    />
  ));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM