Reputation: 1187
I am using react-bootstrap-table to render a table. I grab information from an API and then I want the table to re-render. I am very new to react, and quite figure out where to set the state with the data so that my table will render properly after receiving the data. If I set the data directly in the render (not from the API), this renders actual information, so it's not the table setup.
Below is what I have so far. I've tried a few different places, so if it is completely wrong, please bear with me.
import React, { Component } from 'react';
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css';
import $ from 'jquery';
class Table extends Component {
constructor(props) {
super(props);
//Controlled Component
this.state = {
poData: []
};
}
componentDidMount() {
var pos = [];
function myCallBack(data) {
// place your code here to do the work
var obj = JSON.parse(data);
// sample processing debug statements
var s = 'retrieved this data from suitelet: ';
console.log(s + data);
//alert(s + data);
return obj;
}
function getPOs() {
var obj2 = [];
alert("hi");
// name of the call back function that drives the JSONP mechanism; this string must be the same
// as your function that will ultimately process your request.
var cb = 'myCallBack'
//produce the JSON payload; JQuery will automatically add it to the URL for a JSONP call.
var data = { id: '24567', user: '23455' };
//note JQuery wants to see "callback=?" at the end of the URL; it tells the .getJSON call that this JSON request is of type JSONP
var url = 'https://myapi.com&callback=?';
//finally, the call. For convenience, we sent the data to our custom myCallBack function -- yet not mandatory in this implementation; the call back is in
// already referenced via the .done() method. Other JQuery capacities are can take care of failed calls
$.getJSON(url, data)
.done(function (data) {
obj2 = myCallBack(data);
})
return obj2;
}
var obj2 = getPOs();
this.setState({ poData: obj2 });
}
componentWillUnmount() {
this.setState({ poData: [] });
}
render() {
var poData = this.state.poData;
return (
<div>
<BootstrapTable data={poData} className="table" version='4'>
<TableHeaderColumn dataField='poID' isKey>PO ID</TableHeaderColumn>
<TableHeaderColumn dataField='poName'>PO Name</TableHeaderColumn>
<TableHeaderColumn dataField='poShipDate'>PO Ship Date</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default Table;
EDIT:
Okay, I have cleaned it up some. I tried the componentDidMount stuff mentioned below, but my data never updates.
What I have below will now actually change the state properly, but it still never actually updates the table. Any ideas?
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Login from './Components/Login';
import Table from './Components/Table';
import $ from 'jquery';
class App extends Component {
constructor(props) {
super(props)
// the initial application state
this.state = {
isLoggedIn: false,
username: '',
password: '',
poData: []
};
}
componentDidMount() {
//TODO
}
signIn(username, password) {
// This is where you would call Firebase, an API etc...
// calling setState will re-render the entire app (efficiently!)
this.setState(
{
username: username,
password: password,
isLoggedIn: true,
poData: []
}
)
}
updateTable(poData) {
this.setState({
poData: poData
});
}
render() {
// Here we pass relevant state to our child components
// as props. Note that functions are passed using `bind` to
// make sure we keep our scope to App
return (
<div>
{
(this.state.isLoggedIn) ?
<div>
<Table data={this.state.poData} onUpdate={this.updateTable.bind(this)} />
</div>
:
<div>
<Login onSignIn={this.signIn.bind(this)} />
</div>
}
</div>
)
}
}
export default App;
and Table.js
import React, { Component } from 'react';
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table';
import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css';
import $ from 'jquery';
import App from '../App';
class Table extends Component {
constructor(props) {
super(props);
this.state = {
poData: []
};
this.getPOs = this.getPOs.bind(this);
}
getPOs() {
var url = 'https://myapi.com';
//CORS URL so that we can ignore the stupid CORS stuff
var proxyURL = 'https://cryptic-headland-94862.herokuapp.com/';
fetch(proxyURL + url).then(response => response.json().then(data => {
console.log(data);
console.log(data.length);
this.props.onUpdateTable(data);
}));
}
componentDidMount() {
//this.getPOs();
}
componentWillUnmount() {
//this.setState({ poData: [] });
}
render() {
this.getPOs();
return (
<div>
<BootstrapTable data={this.state.poData} className="table" version='4'>
<TableHeaderColumn dataField='poID' isKey>PO ID</TableHeaderColumn>
<TableHeaderColumn dataField='poName'>PO Name</TableHeaderColumn>
<TableHeaderColumn dataField='poShipDate'>PO Ship Date</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
}
export default Table;
Upvotes: 0
Views: 935
Reputation: 17239
You should make the fetch request and store the result in state
in ComponentDidMount()
. You need to have a done()
after your fetch, and then within that pass the data to state
.
Upvotes: 1