I have data stored in an object and I want to loop through the data and set it as the props for my component.
My component is a card, and I want to show a card for every piece of data in the loop.
This is code so far -
function App() {
let title = [];
for (let key in projectDataObject) {
let newObj = projectDataObject[key].sites;
for (let key in newObj) {
title = newObj[key].title;
}
return (
<div className="App">
<header className="App-header">
<Card title={title}></Card>
</header>
</div>
);
}
}
export default App;
The problem here is because of the "return" it stops the loop at the first item, and does not loop through everything else.
How can I do this?
use it like this:
<div className="App">
<header className="App-header">
{Object.keys(yourObject).map(function(key) {
return <Card title={yourObject[key].title} />;
})}
</header>
</div>
This code doesn't make any sense. You're just taking the last one as the title, so looping is pointless.
for (let key in newObj) {
title = newObj[key].title;
}
Since I can't really tell what you're trying to do there, I'll make an assumption to get you pretty close. It looks like you're trying to pull out all of the titles from your object graph, so let's do that first.
function App() {
const titles = /* I can't tell what your data structure is,
so flatten it to get all of the titles out and into an array here */
return (
<div className="App">
<header className="App-header">
{/* this will put a list of cards in the header */}
{titles.map(title => <Card title={title}/>)}
</header>
</div>
);
}
}
export default App;
Related
I have my component CountDownSquare I want to disappear once the timer is done fully counting down. I have Data in homePageData that holds the main text in a h3 element, this text should appear once the timer is fully done. Here's a ternary statement I attempt to assign but it isn't assigned to anything the way I thought it would be. Here is a snippet of what I thought of
const { homePageData } = props;
{homePageData[0].showCountdown ? <CountDownSquare/>: styles.homeBody}
return (
homePageData && (
<Layout>
<div className={styles.Home}>
<Image src={wordmark} alt="Hammer and Hope wordmark" />
<CountDownSquare >
</CountDownSquare>
{/* <div className={styles.homeBody}>
<h3 className={styles.mainText}>{homePageData[0].mainText}</h3> */}
<Nav />
</div>
</Layout>
)
);
} ```
I am assuming homePageData[0].showCountDown is a boolean which is true if the countdown is complete in the parent component.
You need to add conditions while rendering your component.
The following snippet will render the CountDownSquare component and the h3 tag with homePageData[0].mainText if homePageData[0].showCountdown is true.
const { homePageData } = props;
return (
homePageData ?? (
<Layout>
<div className={styles.Home}>
<Image src={wordmark} alt="Hammer and Hope wordmark" />
{homePageData[0].showCountdown ??
<CountDownSquare >
</CountDownSquare>
<div className={styles.homeBody}>
<h3 className={styles.mainText}>{homePageData[0].mainText}</h3>
</div>
}
</div>
</Layout>
)
);
This question already has answers here:
When should I use a return statement in ES6 arrow functions
(6 answers)
Why doesn't my arrow function return a value?
(1 answer)
Closed 1 year ago.
I know this is kind of a basic question... but I am just learning React and am not so familiar with Javascript as well.
App.js
return (
<div >
<h1>My Weather dashboard</h1>
<div className="container">
{weatherCards.map((obj, index) => {
<Card {...obj}/>
})}
</div>
</div>
)
Card.js
const Card = ( props ) => {
return (
<div className="card">
<img src={props.iconLink}/>
<div className="caption">{props.iconName}</div>
<h3>Day: {props.day}</h3>
<h3>time: {props.time}</h3>
<h3>temperature: {props.temperature}</h3>
</div>
)
}
export default Card
The map does not seem to be displaying anything.
Looks like you forgot the return in the map method
<div className="container">
{weatherCards.map((obj, index) => {
return <Card {...obj}/>
})}
</div>
You can directly return the component like below
return (
<div >
<h1>My Weather dashboard</h1>
<div className="container">
{weatherCards.map((obj, index) => <Card {...obj}/>)}
</div>
</div>
)
So in arrow function if you give anything after => that will be returned on every iteration. So if you give {}-Which is a function body it will return the function body. But if you give any variable or Componenet it will directly return that. We do this if we need to return any plain object.But sometime you have to do some logical execution, that time you can define a function body. But as you are defining a function body you must use the return key like this below
return (
<div >
<h1>My Weather dashboard</h1>
<div className="container">
{weatherCards.map((obj, index) => {
// your code here
return <Card {...obj}/>
})}
</div>
</div>
)
**I have a code that displays the news of the day. https://ibb.co/QMLY2Kx I have 10 classes named "block". Inside the "block" class there are two classes named "blockText". I need to get two different class names and not the same, I want to get this result "blockText1" and "blockText2". How to do it? **
import React from 'react';
import newsStyle from './News_module.css';
export class News extends React.Component {
render() {
const resultsRender = [];
for (var i = 0; i < this.props.news.length; i += 2) {
resultsRender.push(
<div class="block">
{
this.props.news.slice(i, i + 2).map((news, index) => {
return (
<div class="blockText" key={index}>
<p class="text">{news.title}</p>
{console.log(this.props.news.length)}
</div>
);
}
)
}
</div>
);
}
return (
<div>
<div className="headlineSecond">
<div className="Second">
{resultsRender}
</div>
</div>
</div>
);
}
}
You can use ternary operator for this . Here is an example where i chose the value of class based on the value of index and deciding upon whether it is even or odd
<div class={ index%2 ===0 ? "blockText1": "blockText2" } key={index}>
..... rest of code
</div>
I'm fairly new to ReactJS. I am looking to get the value inside a <div> when contentEditable is set to true.
const listResults = this.state.results['1'].map((result) =>
<div key={result.toString()} contentEditable="true">
{result}
</div>
);
return (
<h1> listResults </h1>
<div> {listResults} </div>
)
I am currently outputting a list into pre-filled text-boxes which allows the user to edit them. I am looking to add in a button which once clicked captures the data inside all of the text-boxes. Can anyone point me in a direction on how to capture the changed data.
It may also be worth noting I am using ReactJS on the client side through a CDN.
To get value of editable div:
class App extends React.Component {
constructor(){
super();
this.state = {
arr: [1,2,3,4,5]
}
this.change = this.change.bind(this);
}
change(e, index){
let tmpArr = this.state.arr;
tmpArr[index] = e.target.textContent;
this.setState({arr: tmpArr})
}
render(){
console.log(this.state);
return (
<tr>
{this.state.arr.map((el, index) => <td key={index} id="test" onBlur={(e) => this.change(e, index)} contentEditable="true">{el}</td>)}
</tr>
);
}
}
https://jsfiddle.net/69z2wepo/84647/
One note, you can't return two elements on the same level:
return (
<h1> listResults </h1>
<div> {listResults} </div>
)
It should be wrapped like this:
return (
<div>
<h1> listResults </h1>
<div> {listResults} </div>
</div>
)
I have an array[] of tracks that I receive from an API.
I pass it to a map function which will return a track for every track in tracks. I want to export a variable (Song) specific to that track to be be processed in my event handler as such. The only thing thats not working is the scope of song. I cant set the state of song in my map function or the component goes into an infinite rerender loop.
handleEnter(){
//I want to get the song into this context and play it here
this.props.mouseEnter();
}
handleLeave(){
//same for pausing
this.props.mouseLeave();
}
createTrack(track){
var song = new Audio([track.preview_url]);
return (
<div className="image" key={track.id}>
<img
className="img-circle"
src={track.album.images[0].url}
onMouseEnter={this.handleEnter.bind(this)}
onMouseLeave={this.handleLeave.bind(this)}
/>
<p className="showMe"><span>{track.name}</span></p>
</div>
);
}
getTracks(){
if(this.props.tracks) {
console.log(this.props.tracks);
return (
<div>{this.props.tracks.map(track => this.createTrack(track))}</div>
);
}
}
componentWillMount(){
this.props.fetchMessage();
}
render(){
return(
<div>{this.getTracks()}</div>
)
}
if you want to use .bind, you can send it to handleEnter and handleLeave.
handleEnter( trackID ) {
// trackID available here
}
createTrack(track){
var song = new Audio([track.preview_url]);
return (
<div className="image" key={track.id}>
<img
className="img-circle"
src={track.album.images[0].url}
onMouseEnter={this.handleEnter.bind( this, track.id )}
onMouseLeave={this.handleLeave.bind( this, track.id )}
/>
<p className="showMe"><span>{track.name}</span></p>
</div>
);
}
It's typically best practice to not use .bind in react since it creates a new function on every render. Rather, you should create a <Track /> component, pass it the track, then pass handleEnter and handleLeave as props.
const track = ( props ) => {
let { track, handleEnter, handleLeave } = props;
const onMouseEnter = () {
handleEnter( track.id );
}
const onMouseLeave = () {
handleLeave( track.id );
}
return (
<div className="image" key={track.id}>
<img
className="img-circle"
src={track.album.images[0].url}
onMouseEnter={ onMouseEnter }
onMouseLeave={ onMouseLeave }
/>
<p className="showMe">
<span>{track.name}</span>
</p>
</div>
);
};
then in your render, you'd map like you're doing and output <Track /> pure components instead of full-on components
Have a look at this. Hopefully it will solve your problem.
handleEnter(track, e){
// you will get the full track object and use the data
this.props.mouseEnter();
}
handleLeave(track, e){
// you will get the full track object and use the data
this.props.mouseLeave();
}
componentWillMount(){
this.props.fetchMessage();
}
render(){
const createTrack = (track, index) => {
var song = new Audio([track.preview_url]);
return (
<div className="image" key={'track-'+ index}>
<img
className="img-circle"
src={track.album.images[0].url}
onMouseEnter={this.handleEnter.bind(this, track)}
onMouseLeave={this.handleLeave.bind(this,track)}
/>
<p className="showMe"><span>{track.name}</span></p>
</div>
);
}
return(
<div>{this.props.tracks ? this.props.tracks.map(createTrack) : null }</div>
)
}