Diego Oriani Diego Oriani - 1 year ago 62
React JSX Question

React — Passing data between siblings and iterating it

I have two questions, the first is about passing data between components and the second is about the component hierarchy.

Right now, in the

Data
component I am trying to set the
name
property and pass it to a
ListItem
component that should iterate based on the API request. I tried many things without success. What am I doing wrong? Does the data needs to be iterated when setting the new state? Am I passing it correctly?

Basic pseudocode


  • Read data from API

  • Set data to the component state

  • Create siblings components based on data stored

  • Render components



The second question is about the hierarchy of the components. I keep reading around the web that the data request should be setup at the top and separated. Having this in place, the other components would feed from this data and execute. Finally, the
App
component would render all this components accordingly. From the example below, am I going to the right track? Was I correct to creating a component specific for data request or should this be done in the
App
component?

I understand these questions might be basic but it is something that I am really struggling to understand and I would appreciate if someone can help me understand or point me to a basic example that I can digest.

Thank you in advance. (Sorry, I had more than two questions.)

class App extends React.Component {
render() {
return (
<ul>
<ListItem name={this.state.name} />
</ul>
)
}
}


class Data extends React.Component {
constructor(props) {
super(props)
this.state = {
name: '',
requestFailed: false,
}
}

componentDidMount() { // Executes after mouting


fetch('https://api.tfl.gov.uk/BikePoint')
.then((response) => {
return response.json()
}).then((d) => {
console.log('parsed json', d[0].commonName)
this.setState({
name: d.commonName
});
}).catch(function(ex) {
console.log('parsing failed', ex)
this.setState({
requestFailed: true
})
})
}

render() {

if(this.state.requestFailed) return <p>Request failed.</p>
if(!this.state.name) return <p>Loading</p>

const namesList = names.map(function(name, index){
return <ListItem key={index} name={this.state.name} />
})

return <ul>{ namesList }</ul>
}
}

class ListItem extends React.Component {
render() {
return <li> { this.props.name } </li>
}
}

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


CodePen

Answer Source

Where to start -

First, your App component needs to render Data component. React works in the way that parent element always renders children elements and what is not rendered doesn't exist.

Then, you need to remap response to names, if that is what you wanted to do - I am not sure.

In render method, you want to take name out of mapping function, not from state. I also removed name state, you really want to keep names instead of one name. There is a lot of small thing I had to adjust to make it work, so I will just post working code pen here, so you can see what needed to be done.

https://codepen.io/anon/pen/eEmqxX?editors=0010

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download