Reputation: 971
I'm new to REACT and learning a ton. I am trying to retrieve my data from a SharePoint list and render it to a page as a table but when I make my axios call, I get the following error. tblData is undefined
I know why I get the error and it's because the this
in the axios is different from the outside, so I turned it into an arrow function and it still didn't work. I then assigned the outer this
to a variable and used it in the axios scope but that still didn't work. Please help with!!
function Table(props) {
return (
<tr>
<td>{props.title}</td>
<td>{props.fname}</td>
<td>{props.lname}</td>
<td>{props.phone}</td>
<td>{props.age}</td>
</tr>
)
}
function App() {
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('Axios List')/items";
var tbl = this;
axios.get(endPointUrl).then(response => {
tbl.tblData = response.data.value.map(function (data) {
return (
<Table
title={data.Title}
fname={data.FirstName}
lname={data.LastName}
phone={data.Phone}
age={data.age}
/>
)
})
})
return (
{ tblData }
)
}
ReactDOM.render(
<App />,
document.getElementById("app")
)
Any help would be much appreciated.
When I console.log(response.data.value), I get
Upvotes: 0
Views: 279
Reputation: 2983
At first you should understand the fundamentals of React and thus that functional components are not just normal functions where you can mutate this
scope and it will be magically available in the render methods.
React operates against virtual DOM and diffing is being done when it is needed (when state changes) but state !== this.
More about lifecycle of components is here https://reactjs.org/docs/state-and-lifecycle.html
In your comments you linked https://codesandbox.io/s/render-styled-table-with-data-iou7k?file=/components/App.js which works, and it works because of simple reason, there is no another lifecycle of component. Data is static and not asynchronous and on first render it works with this
.
However when you are fetching data from API you are making asynchronous code through promises https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
When you work with promises react component needs to be "informed" that it should re-rerender the DOM
function Table(props) {
return (
<tr>
<td>{props.title}</td>
<td>{props.fname}</td>
<td>{props.lname}</td>
<td>{props.phone}</td>
<td>{props.age}</td>
</tr>
)
}
function App() {
const [data, setData] = React.useState()
var endPointUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbyTitle('Axios List')/items"
React.useEffect(() => {
axios.get(endPointUrl).then(response => setData(response.data))
}, [])
return (
<React.Fragment>
{data && data.value.map(_data => (
<Table
title={_data.Title}
fname={_data.FirstName}
lname={_data.LastName}
phone={_data.Phone}
age={_data.age}
/>
)}
</React.Fragment>
)
}
ReactDOM.render(
<App />,
document.getElementById("app")
)
Now your component will enter a several lifecycle states:
return ( data && )
condition will evaluate to false which will render nothing.React.useEffect
we will trigger loading of data https://reactjs.org/docs/hooks-effect.htmlsetData
which will trigger react reconciliation and re-rendering and data
will be accessible.Upvotes: 1