I have a data like this
const data = ["https://via.placeholder.com/60x60",
"https://via.placeholder.com/60x60",
"https://via.placeholder.com/60x60",
"https://via.placeholder.com/60x60"];
not the pair of key and value.
I want to make it by mapping like,
<div>
<img src={} />
<img src={} />
<img src={} />
<img src={} />
<div>
so coded
<div className="App">
{data.map((item) => {
<img src={item}/>
})}
</div>
but it does not work.
can any one help me?
Without Scope
<div className="App">
{data.map((item, key) => (
<img src={item} key={key} />
))}
</div>
With Scope
<div className="App">
{data.map((item, key) => {
return <img src={item} key={key} />;
})}
</div>
Related
I am working on a list of pokemons app like in this tutorial: https://www.youtube.com/watch?v=XehSJF85F38&t=5904s
But I have problem, for some reason my routes don't work, and I did everything like in tutorial.
Here is my code:
function App() {
return (
<Router>
<div className="App">
<NavBar />
<div className="container">
<Switch>
<Route exact path="/"></Route>
<Route exact path="pokemon/:pokemonIndex" component={Pokemon} />
</Switch>
<Body />
</div>
</div>
</Router>
);
}
And I call it in another component:
render() {
return (
<div className="col-md-4 col-sm-6 mb-3">
<Link to={`pokemon/${this.state.pokemonIndex}`} className="cardLink">
<div className="card cardeffect">
<h5 className="card-header">
{this.state.pokemonIndex}. {this.state.pokemonName.toUpperCase()}
</h5>
{this.state.imageLoading ? (
<img
src={loading}
style={{ width: "6em", height: "6em" }}
className="card-img-top mx-auto mt-2"
/>
) : null}
<div className="card-body mx-auto">
<Sprite
className="card-image-top mx-auto mt-2"
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ request: true })}
src={this.state.imageUrl}
style={
this.state.tooManyRequest
? { display: "none" }
: this.state.imageLoading
? { display: "none" }
: { display: "block" }
}
></Sprite>
</div>
</div>
</Link>
</div>
);
}
But when I click on any of cards, URL changes but that is all, nothing more happen.
Ey!
I am not sure but I think Link is not fitted for what you want to do. It's ok to create a link on a navbaritem for instance but not to trigger redirection onclick.
Maybe try to use an onclick event on your card with the Redirect component. Something like this might work:
<div className="card-body mx-auto" onclick={() => {return <Redirect to=`pokemon/${this.state.pokemonIndex}`}>
<Sprite
className="card-image-top mx-auto mt-2"
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ request: true })}
src={this.state.imageUrl}
style={
this.state.tooManyRequest
? { display: "none" }
: this.state.imageLoading
? { display: "none" }
: { display: "block" }
}
>
</Sprite>
</div>
You might also be able to trigger the event directly in the Sprite component, Idk this package.
Hopping it will help !
It will be useful for you to do this from the root while defining the route.
function App() {
return (
<Router>
<div className="App">
<NavBar />
<div className="container">
<Switch>
<Route exact path="/"></Route>
<Route path="/pokemon/:pokemonIndex" component={Pokemon} />
</Switch>
<Body />
</div>
</div>
</Router>
);
}
and
render() {
return (
<div className="col-md-4 col-sm-6 mb-3">
<Link to={`/pokemon/${this.state.pokemonIndex}`} className="cardLink">
...
...
</Link>
</div>
);
Hey guys I am trying to pass a URL for background image into the ResultsItem component. My problem is that the state of places is not defined until data are fetched. The problem is with the const Thumbnail. I always get an error of "TypeError: Cannot read property 'photos' of undefined".
render() {
const Thumbnail = `https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=${places.photos.photoreference}&key=MYAPIKEY
`;
return (
<div>
<div className="flex align-center">
<div className="search">
<SearchInput
id="autocomplete"
placeholder="Search by address"
width="100%"
height={56}
/>
<Script
url="https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&libraries=places,geometry&callback=initAutocomplete"
onLoad={this.handleScriptLoad}
/>
</div>
<div className="current-location">
<Tooltip content="Use current location">
<IconButton
icon="locate"
iconSize={16}
height={32}
onClick={this.currentLocationOnClick}
>
{this.state.lat} & {this.state.lng}
</IconButton>
</Tooltip>
</div>
</div>
<div className="results">
{this.state.places.map(places => (
<div className="results-item" onClick={this.props.sideBarOpen}>
<ResultsItem name={places.name} image={Thumbnail} />
</div>
))}
</div>
</div>
);
}
}
The fact that places is available in an async manner, the best solution is to resolve Thumbnail within the map function itself.
That way it will only be required and resolved when places is available
render() {
return (
<div>
<div className="flex align-center">
<div className="search">
<SearchInput
id="autocomplete"
placeholder="Search by address"
width="100%"
height={56}
/>
<Script
url="https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&libraries=places,geometry&callback=initAutocomplete"
onLoad={this.handleScriptLoad}
/>
</div>
<div className="current-location">
<Tooltip content="Use current location">
<IconButton
icon="locate"
iconSize={16}
height={32}
onClick={this.currentLocationOnClick}
>
{this.state.lat} & {this.state.lng}
</IconButton>
</Tooltip>
</div>
</div>
<div className="results">
{this.state.places.map(places => {
const Thumbnail = `https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=${places.photos.photoreference}&key=MYAPIKEY
`;
return(
<div className="results-item" onClick={this.props.sideBarOpen}>
<ResultsItem name={places.name} image={Thumbnail} />
</div>
)})}
</div>
</div>
);
}
}
You should prevent to load data before they are actually loaded from server, so you should render a loader before use your result in this way:
if(isLoading) { // You should set the loading state before to load data from server
return <span>Loading</span>
}
return ( // This shows your data after loading goes to false
<div>Your code here</div>
)
I am very new to react and I am trying to show data
but I am getting the error
No Data is appear when i add some code about image_url, title,source_url etc....
TypeError: Cannot read property 'image_url' of undefined
In Recipe.js,
import React, { Component } from 'react'
export default class Recipe extends Component {
render() {
const {
image_url,
title,
source_url,
publisher,
recipe_id
} = this.props.recipe;
return (
<React.Fragment>
<h1>Recipe</h1>
<div className="col-10 mx-auto col-md-6 col-lg-4">
<div className="card">
<img src={image_url} className="img-card-top" style={{height:"14rem"}} alt="recipe" />
<div className="card-body text-capitalize">
<h5>{title}</h5>
<h6 className="text-warning text-slanted">
provided by {publisher}
</h6>
</div>
<div className="card-footer">
<button type="button" className="btn btn-outline-primary">Details</button>
Recipe url
</div>
</div>
</div>
</React.Fragment>
);
}
}
In ReactList.js,
<div className="row">
{recipes.map (recipe => {
return <Recipe key={recipe.recipe_id} recipe={recipe}
/>;
})}
</div>
</div>
<Recipe />
</React.Fragment>
error occur as you use two time <Recipe /> in RecipeList.js,
Removed one <Recipe />,
error will solve
Change
<div className="row">
{recipes.map (recipe => {
return <Recipe key={recipe.recipe_id} recipe={recipe}
/>;
})}
</div>
</div>
<Recipe />
</React.Fragment>
To
<div className="row">
{recipes.map (recipe => {
return <Recipe key={recipe.recipe_id} recipe={recipe}
/>;
})}
</div>
</div>
</React.Fragment>
I tried to put elements into CustomModal variable:
const CustomModal = (<div className="peoplelistpage-modal">
<div className="peoplelistpage-modal-content-empty" />
<div className="peoplelistpage-modal-content">
<CustomForm
krNameInput={this.state.krNameInput}
handleKrNameInput={this.handleKrNameInput}
enNameInput={this.state.enNameInput}
handleEnNameInput={this.handleEnNameInput}
positionInput={this.state.positionInput}
handlePositionInput={this.handlePositionInput}
departmentInput={this.state.departmentInput}
handleDepartmentInput={this.handleDepartmentInput}
doingInput={this.state.doingInput}
handleDoingInput={this.handleDoingInput}
btnValue="add"
onBtnClick={this.handlePersonAddBtn}
/>
</div>
<div className="peoplelistpage-modal-content-empty" />
</div>);
and used it in render() like this:
render() {
//...
{ CustomModal }
//...
but, got an error:
react-dom.development.js:57 Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {CustomModal}). If you meant to render a collection of children, use an array instead.
Is there are any way to put elements into variable for naming?
Thanks.
----update-----
This is my full code of render :
render() {
const CustomModal = (<div className="peoplelistpage-modal">
<div className="peoplelistpage-modal-content-empty" />
<div className="peoplelistpage-modal-content">
<CustomForm
krNameInput={this.state.krNameInput}
handleKrNameInput={this.handleKrNameInput}
enNameInput={this.state.enNameInput}
handleEnNameInput={this.handleEnNameInput}
positionInput={this.state.positionInput}
handlePositionInput={this.handlePositionInput}
departmentInput={this.state.departmentInput}
handleDepartmentInput={this.handleDepartmentInput}
doingInput={this.state.doingInput}
handleDoingInput={this.handleDoingInput}
btnValue="add"
onBtnClick={this.handlePersonAddBtn}
/>
</div>
<div className="peoplelistpage-modal-content-empty" />
</div>);
const { people } = this.props.people.state;
return (
<React.Fragment>
{/* check login */}
{this.props.auth.state.isLoggedIn ? (
{ CustomModal }
) : (
<div />
)}
<div className="peoplelistpage-main">
<h1 className="peoplelistpage-title">people list</h1>
<div className="peoplelistpage-list-container">
{people.map((person, index) => (
<ul className="peoplelistpage-list-ul" key={index}>
<li className="peoplelistpage-list-li">
{`${index + 1}.`}{" "}
<Link to={`${this.props.location.pathname}/${person.id}`}>
{person.kr_name}
</Link>{" "}
<button onClick={this.handlePersonDeleteBtn(person.id)}>
<DeleteUserIcon />
</button>
</li>
</ul>
))}
</div>
<button onClick={this.openModal}>add</button>
</div>
</div>
) : (
<CustomNotPermittedForm />
)}
</React.Fragment>
);
}
Yes, you can use a div or a React.Fragment to group elements together. divs are added to the DOM while Fragments are not. But in order for this work with state, you will have to use a function, as a static variable does not get updated with state values.
const CustomModal = () => (
<React.Fragment> // <-- or div
<div className="peoplelistpage-modal">
<div className="peoplelistpage-modal-content-empty" />
<div className="peoplelistpage-modal-content">
<CustomForm
krNameInput={this.state.krNameInput}
handleKrNameInput={this.handleKrNameInput}
enNameInput={this.state.enNameInput}
handleEnNameInput={this.handleEnNameInput}
positionInput={this.state.positionInput}
handlePositionInput={this.handlePositionInput}
departmentInput={this.state.departmentInput}
handleDepartmentInput={this.handleDepartmentInput}
doingInput={this.state.doingInput}
handleDoingInput={this.handleDoingInput}
btnValue="add"
onBtnClick={this.handlePersonAddBtn}
/>
</div>
<div className="peoplelistpage-modal-content-empty" />
</div>
</React.Fragment>
);
Usage
render() {
// ...
<CustomModal />
// ...
I have some JSX that is giving me the error:
Warning: Each child in a list should have a unique "key" prop
which I've run across before, but this time I can't see where the problem is. The markup is as follows:
return isLoading ? (
<div className="App">
<div className="spinner"></div>
<div className="App loading">
<p><i>loading...</i></p>
</div>
</div>
)
: hasError ? (
<div className="App loading-error">
⚠ There is a network issue: Please try again later
</div>
)
:
(
<div className="App" key={`op - ${Math.floor(Math.random() * 110)}`}>
<>
{shelves.map(s => {
return (
books[s].map((b,i) => {
return (
<>
<h2>{((shelvesN.filter(o => o.value === s)))[0].label}</h2>
<div key={`${s}-${i}`}>
<Link to={`/book/${b.id}`}>
<img src={b.imageLinks.thumbnail} alt={b.title}></img>
</Link>
<Select className="sel-x"
placeholder="Choose a bookshelf..."
value={""}
options={shelvesN}
onChange={opt => changeShelf(opt.value,b.id)}
/>
</div>
</>
)
})
)
})}
</>
</div>
)
I'd appreciate any help. Thanks.
k.
So, the way i see it, you are stuck here:
<div className="App" key={`op - ${Math.floor(Math.random() * 110)}`}>
<>
{shelves.map(s => {
return (
books[s].map((b,i) => {
return (
<>
<h2>{((shelvesN.filter(o => o.value === s)))[0].label}</h2>
<div key={`${s}-${i}`}>
<Link to={`/book/${b.id}`}>
<img src={b.imageLinks.thumbnail} alt={b.title}></img>
</Link>
<Select className="sel-x"
placeholder="Choose a bookshelf..."
value={""}
options={shelvesN}
onChange={opt => changeShelf(opt.value,b.id)}
/>
</div>
</>
)
})
)
})
this block contains 2 maps, which returns lists.
the inner one shouldn't use <>, because it needs the key reference, so should the first one. something like:
shelves.map((s, I) => {
return (
<div key={I}>
{books[s].map((b,i) => {
return (
<div key={`${I}-${i}`}>
<h2>{((shelvesN.filter(o => o.value === s)))[0].label}</h2>
<div >
<Link to={`/book/${b.id}`}>
<img src={b.imageLinks.thumbnail} alt={b.title}></img>
</Link>
<Select className="sel-x"
placeholder="Choose a bookshelf..."
value={""}
options={shelvesN}
onChange={opt => changeShelf(opt.value,b.id)}
/>
</div>
</div>
</>
)
})}
</div>)
}
You are returning React.Fragment from each array item, so assign the unique key to each Fragment, here:
books[s].map((b,i) => { return ( <> ..... </> )})
Use this code:
<div className="App" key={`op - ${Math.floor(Math.random() * 110)}`}>
<>
{shelves.map(s => {
return (
books[s].map((b,i) => {
return (
// ↓↓↓↓↓↓↓↓ add key here
<React.Fragment key={i}>
<h2>{((shelvesN.filter(o => o.value === s)))[0].label}</h2>
<div>
<Link to={`/book/${b.id}`}>
<img src={b.imageLinks.thumbnail} alt={b.title}></img>
</Link>
<Select className="sel-x"
placeholder="Choose a bookshelf..."
value={""}
options={shelvesN}
onChange={opt => changeShelf(opt.value,b.id)}
/>
</div>
</React.Fragment>
)
})
)
})}
</>
</div>
You use iteration, which means you must use keys. topic
Your code looks awful and unreadable, you should work better on the style.
shelves.map((s, I) => {
return (
<div key={I}>
{books[s].map((b,i) => {
return (
<div key={`${I}-${i}`}>
<h2>{((shelvesN.filter(o => o.value === s)))[0].label}</h2>
<div >
<Link to={`/book/${b.id}`}>
<img src={b.imageLinks.thumbnail} alt={b.title}></img>
</Link>
<Select className="sel-x"
placeholder="Choose a bookshelf..."
value={""}
options={shelvesN}
onChange={opt => changeShelf(opt.value,b.id)}
/>
</div>
</div>
</>
)
})}
</div>)
}