Alessander França Alessander França - 5 months ago 16
Ajax Question

React ajax render

I'm having troubles to render my components with ajax data.

I do not know how to insert a component inside my render with the ajax data.

Here is my AccountPage.js

import Close from '../../icons/Close'
import Delete from '../../icons/Delete'
import Edit from '../../icons/Edit'
import List from '../../icons/List'
import AccountSimple from './AccountSimple'
import '../../../../css/accounts.css'

class AccountPage extends React.Component{
constructor(props){
super(props);
this.state = {
data: null,
first_name: '',
account: '',
address: '',
tableBody: undefined

};

}

componentDidMount() {
this.tableBody = document.getElementById("table-body");
this.serverRequest = $.get("/api/client.json", function (result) {
var client = result;
this.setState({
data: client,
});
}.bind(this));

}

componentDidUpdate() {
// logs all objects from ajax
console.log(data);
}

render() {

return (
<div className="contactto-middle-content">
<h1 className="account-title">Usuários</h1>
<div className="account-table">
<div className="account-table-row account-table-row-header">
<div className="account-table-row-header-td account-table-td-name">Nome</div>
<div className="account-table-row-header-td account-table-td-account">Conta</div>
<div className="account-table-row-header-td account-table-td-address">Endereço</div>
<div className="account-table-row-header-td account-table-td-actions">Ações</div>
</div>
<div id="table-body" className="account-table-row account-table-row-body">

</div>
</div>
</div>

);
}
}

export default AccountPage


The AccountPage imports the AccountSimple

'use strict'

import React from 'react'
import Done from '../../icons/Done'
import Close from '../../icons/Close'
import Delete from '../../icons/Delete'
import Edit from '../../icons/Edit'
import List from '../../icons/List'
import '../../../../css/accounts.css'

class AccountSimple extends React.Component{
constructor(props){
super(props);
this.state = {
first_name: '',
account: '',
address: ''

};
}

componentDidMount() {
this.setState({
first_name: this.props.acc.first_name,
last_name: this.props.acc.last_name,
account: this.props.acc.account,
address: this.props.acc.address
});
console.log(this.props.acc);

}

render() {

return (
<div className="account-table-row-body-tr">
<div className="account-table-row-body-td account-table-td-name">{this.state.first_name} {this.state.last_name}</div>
<div className="account-table-row-body-td account-table-td-account">{this.state.account}</div>
<div className="account-table-row-body-td account-table-td-address">{this.state.address}</div>
<div className="account-table-row-body-td account-table-td-actions">
<List svgClass="account-table-td-actions-list" width="24" height="24" />
<Edit svgClass="account-table-td-actions-edit" width="24" height="24" />
<Delete svgClass="account-table-td-actions-delete" width="24" height="24" />
</div>
</div>

);
}
}

export default AccountSimple


What I want is render # inside the render of AccountPage.

Thanks in advance.

Answer

If I understand correctly, you'll want to .map over the objects in data (assuming it's an array) and create an AccountSimple component for each. You don't need state in AccountSimple - just use props.

Inside AccountPage#render:

<div id="table-body" className="account-table-row account-table-row-body">
    { data && data.map(accountInfo =>
        <AccountSimple {...accountInfo} />
    )}
</div>

This checks whether data has been loaded, and then when it's available, passes each data row as props to AccountSimple.

AccountSimple should probably be a stateless component - it doesn't need a constructor or componentDidMount method, it can just have a render method and refer to this.props instead of this.state.