Passing div data from map in other component - javascript

I am creating Test component using Carousel component.
In Carousel component I am passing div with data from props.But I want to pass img src from testData props as follows.
export default class Test extends Component {
render() {
const { testData } = this.props;
return (
<div>
<Carousel>
{
testData.length && testData.map((a) => (
<div><img src=
{a.link} />
</div>
)
)
}
</Carousel>
</div>
);
}
}
testData = [{"link":"/test1.jpg"},
{"link":"/test2.jpg"},
{"link":"/test3.jpg"}
]
When I do this as follows then it is working fine.
<div> <img src="/test1.jpg" /></div>
<div> <img src="/test2.jpg" /></div>
<div> <img src="/test3.jpg" /></div>
What I am doing wrong using testData.

Regular JavaScript comments are not allowed in JSX:
//<div> <img src="/test1.jpg" /></div>
//<div> <img src="/test2.jpg" /></div>
//<div> <img src="/test3.jpg" /></div>
To comment in JSX you must wrap in { }.
{ /*<div> <img src="/test1.jpg" /></div>
<div> <img src="/test2.jpg" /></div>
<div> <img src="/test3.jpg" /></div>*/ }

import React, { Component } from 'react'
import {Carousel} from 'react-bootstrap'
export default class Test extends Component {
render() {
const testData = [{"link":"/test1.jpg"},
{"link":"/test2.jpg"},
{"link":"/test3.jpg"}]
return (
<Carousel>
{testData.length && testData.map((a) =>
(<div>
<img src={a.link} />
</div>))}
</Carousel>
);
}
}
This piece of code is working fine, So I think the problem lies in how you are passing testData through props.
If you could provide the code where you are passing the testData as props a solution can be found out.

I finally got the issue.
In first case when I am using static data as
testData = [{"link":"/test1.jpg"},
{"link":"/test2.jpg"},
{"link":"/test3.jpg"}
]
It will get showed to page every time component rendered.
But in second case
const { testData } = this.props;
testData is set by API call.So it will not get fetched when component rendered first.To resolve this issue I did this
if (!caurosalData.length) {
return null;
}
Now it is working fine

Related

how to display all image in array react js

how to display Img array all image in react js
data***
import im1 from "../Image/10007.jpg"
export const Data =[
{
name:"aminur",
Img:[im1,im1,im1]
}
]enter code here
code :
import React from 'react'
import "./Content.css"
import { Data } from './data'
const Content = () => {
return (
<div className='content'>
{Data.map((item)=>{
return(
<div className='text'>
<img src={item.Img[0]} alt="" />
</div>
)
})}
</div>
)
}
export default Content
What I understood from your question is how to display all the images under Img array which is inside an another array of objects.
import React from 'react'
import "./Content.css"
import { Data } from './data'
const Content = () => {
return (
<div className='content'>
{Data.map((item)=>{
return(
<div className='text'>
{item?.Img.map(image=>(
<img src={image} alt="" />
))}
</div>
)
})}
</div>
)
}
export default Content

ReactJS Replace Broken Image with a Different Element

Is it possible to replace a broken image with a separate element entirely in reactJS?
My current code uses the onError() function to set a broken image's src
<img src={user.avatar} onError={e => e.target.src = '/static/image.png'} />
What I'd like to do is replace it with some text instead. Something like:
<img src={user.avatar} onError={() => this.replace() } />
replace function(){
return <div class='some-class'>Image not found</div> // Would replace the image element
}
Note* The user.avatar property will always be defined, and I'm not looking to use the alt attribute
Here's how I might do it for a simple image component. We just change what we return if there was an error.
export function UserImageComponent({user}){
const [isError,setIsError] = useState(false);
if(isError){
return <div class='some-class'>Image not found</div> // Would replace the image element
}
return <img src={user.avatar} onError={() => this.setIsError(true) } />
}
You can use this strategy:
class Image extends React.Component {
constructor() {
super();
this.state = {};
this.fallback = () => {
this.setState({ failed: true });
};
}
render() {
if (this.state.failed) {
return <div classname='some-class'>Image not found</div>;
} else {
return <img src={this.props.src} onError={this.fallback} />;
}
}
}
const brokenUrl = 'url.png';
const url = 'https://picsum.photos/536/354';
const app = (
<div>
<h2>Broken image:</h2>
<Image src={brokenUrl} />
<h2>Working image:</h2>
<Image src={url} />
</div>);
ReactDOM.render(app, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

How to call an action from a component without connecting it to the redux store?

I have a Cards component which takes in the props from the UserPostscomponent(which is connected to the store) and displays cards. Cards is not connected to the redux store and I want to dispatch an action in the handleDelete function. How can I do that?
import React, { Component } from "react"
class Cards extends Component {
handleDelete = (id) => {
}
render() {
const { title, description } = this.props.post
const { postId } = this.props.post._id
return (
<div className="card">
<div className="card-content">
<div className="media">
<div className="media-left">
<figure className="image is-48x48">
<img
src="https://bulma.io/images/placeholders/96x96.png"
alt="Placeholder image"
/>
</figure>
</div>
<div className="media-content" style={{border: "1px grey"}}>
<p className="title is-5">{title}</p>
<p className="content">{description}</p>
<button className="button is-success">Edit</button>
<button onClick={this.handleDelete(postId)} className="button is-success">Delete</button>
</div>
</div>
</div>
</div>
)
}
}
export default Cards
UserPosts component which passes the props
<div>
{userPosts &&
userPosts.map(post => {
return <Cards key={post._id} post={post} />
})}
</div>
```
You can use the global store and directly call dispatch method. Not recommended. Hard to maintain and debug.
import { createStore } from 'redux'
const store = createStore(todos, ['Use Redux'])
// Dont create new one, use the one created in root
function addTodo(text) {
return {
type: 'ADD_TODO',
text
}
}
store.dispatch(addTodo('Read the docs'))
store.dispatch(addTodo('Read about the middleware'))

Moving data between react components

So I'm trying to break the component on my App.js into a smaller component, that being my Sidebar.js. I took a small section of the code and put it in its own Sidebar.js file but no matter what I've tried, I cant call my function getNotesRows() from App.js without it being unable to find it or this.states.notes being undefined.
I just want it to send the code back and forth. This is a demo app, so I know it's not the most practical.
import React, { Component } from "react";
import classNames from "classnames";
import logo from "./logo.svg";
import checkMark from "./check-mark.svg";
import "./App.css";
import Sidebar from "./components/Sidebar.js";
class App extends Component {
constructor(props) {
super(props);
this.state = {
notes: [],
currentNoteIndex: 0
};
this.markAsRead = this.markAsRead.bind(this);
this.selectNote = this.selectNote.bind(this);
console.log("Test started 2.25.19 19:23");
}
componentWillMount() {
fetch('/notes')
.then(response => response.json())
.then(
notes => {
this.setState({
notes: notes,
currentNoteIndex: 0
})
}
)
.catch(
error => {
console.log('Ooops!');
console.log(error);
}
);
}
markAsRead() {
this.setState(currentState => {
let marked = {
...currentState.notes[currentState.currentNoteIndex],
read: true
};
let notes = [...currentState.notes];
notes[currentState.currentNoteIndex] = marked;
return { ...currentState, notes };
});
}
selectNote(e) {
this.setState({ currentNoteIndex: parseInt(e.currentTarget.id, 10) });
}
getTotalUnread() {
let unreadArray = this.state.notes.filter(note => {
return note.read === false;
})
return unreadArray.length;
}
getNotesRows() {
return this.props.notes.map(note => (
<div
key={note.subject}
className={classNames("NotesSidebarItem", {
selected:
this.props.notes.indexOf(note) === this.props.currentNoteIndex
})}
onClick={this.selectNote}
id={this.props.notes.indexOf(note)}
>
<h4 className="NotesSidebarItem-title">{note.subject}</h4>
{note.read && <img alt="Check Mark" src={checkMark} />}
</div>
));
}
// TODO this component should be broken into separate components.
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Notes Viewer Test App</h1>
<div>
Unread:
<span className="App-title-unread-count">
{this.getTotalUnread()}
</span>
</div>
</header>
<div className="Container">
<Sidebar />
<section className="NoteDetails">
{this.state.notes.length > 0 && (
<h3 className="NoteDetails-title">
{this.state.notes[this.state.currentNoteIndex].subject}
</h3>
)}
{this.state.notes.length > 0 && (
<p className="NoteDetails-subject">
{this.state.notes[this.state.currentNoteIndex].body}
</p>
)}
{this.state.notes.length > 0 && (
<button onClick={this.markAsRead}>Mark as read</button>
)}
{this.state.notes.length <= 0 && (
<p>
No Notes!
</p>
)}
</section>
</div>
</div>
);
}
}
export default App;
Above is my App.js
and below is the Sidebar.js that I'm trying to create
import React, { Component } from "react";
import "../App.css";
import App from "../App.js";
class Sidebar extends React.Component{
constructor(props) {
super(props);
}
render(){
return (
<section className="NotesSidebar">
<h2 className="NotesSidebar-title">Available Notes:</h2>
<div className="NotesSidebar-list">{App.getNotesRows()}</div>
</section>
)}}
export default Sidebar;
You cannot access a method like that. You need to pass the method as a prop and use it in the child.
<Sidebar getNotesRows={this.getNotesRows} />
and in Sidebar use
<div className="NotesSidebar-list">{this.props.getNotesRows()}</div>
In your sidebar, you're trying to call getNotesRows() from App, but Sidebar doesn't need access to app (you shouldn't have to import App in Sidebar.js). Instead, you should pass the function from App to your Sidebar component, and reference it from Sidebar's props.
In App.js, you'll need to bind getNotesRows and pass it to sidebar.:
<Sidebar getNotesRows={ this.getNotesRows } />
Then in Sidebar.js, you'll need to reference getNotesRows in your render method:
render() {
const notes = this.props.getNotesRows();
return (
<section className="NotesSidebar">
<h2 className="NotesSidebar-title">Available Notes:</h2>
<div className="NotesSidebar-list">{ notes }</div>
</section>
);
}
It seems like the problem here is that you are trying to use a class function as a static property, to put it simply, you have not initialized the App class when you import it into your sidebar(?), thus no static function was found on your App class so you can call App.getNotesRows() maybe you should re-think your components and separate them in container-components using a Composition Based Programming approach instead of OO approach.

How to make a image clickable using document.getElementById in reactjs

I am currently using the Twitch API, where I have created a file that renders the game cover image by searching. I want the user to be able to click the game image, which will redirect them to their proper Twitch Links
Search Response
My code for the game image rendering looks like this:
render() {
const { game } = this.props
return (
<div className="GameDetails">
<img src={this.formatImageUrl(game.box_art_url)} alt="" />
<p>{game.name} </p>
<p>ID: {game.id}</p>
</div>
)
}
}
export default GameImage
I tried out:
render() {
const { game } = this.props
return (
<div className="GameDetails">
<img src={this.formatImageUrl(game.box_art_url)} alt="" onClick${"https://www.twitch.tv/directory/game/${document.getElementById("SearchName").value}"}/>
<p>{game.name} </p>
<p>ID: {game.id}</p>
</div>
)
}
}
export default GameImage
Which gives me an error.
The "SearchName" value is what the user types in the search bar for the game, therefore I want to send them to the respectable twitch pages when clicked.
Of course you will receive an error, because firstly you've misspelled $ with = and secondly, onClick prop expects a function which will handle the action after clicking the image.
Suggested approach:
handleClick = () => {
// logic when user clicks on image
// https://www.twitch.tv/directory/game/${document.getElementById("SearchName").value}
}
render() {
const { game } = this.props
return (
<div className="GameDetails">
<img src={this.formatImageUrl(game.box_art_url)} alt="" onClick={this.handleClick} />
<p>{game.name} </p>
<p>ID: {game.id}</p>
</div>
)
}
export default GameImage
Edit: It's kinda difficult to understand what you really want to achieve, however if you want that img to work as a link, you should consider using a element instead. Just wrap your img tag as well as p into a.
render() {
const { game} = this.props
const link = `https://www.twitch.tv/directory/game/${document.getElementById("SearchName").value}`;
return (
<div className="GameDetails">
<a href={link}>
<img src={this.formatImageUrl(game.box_art_url)} alt="" onClick={this.handleClick} />
<p>{game.name} </p>
<p>ID: {game.id}</p>
</a>
</div>
)
}
If all you want to do is go to another site by clicking on the image simply wrap it in an HTML anchor with the url as the href attribute. Hover over the images (don't click on them) to see the URL in the browser status bar.
function App({ data }) {
return data.map(game => <Details game={game} />);
}
function Details({ game }) {
return (
<div className="gameDetails">
<a href={game.twitch_url}>
<img src={game.box_art_url} />
</a>
</div>
);
}
const data = [
{ id: 1, twitch_url: 'http://game1.com', box_art_url: 'https://dummyimage.com/100x100/000/fff' },
{ id: 2, twitch_url: 'http://game2.com', box_art_url: 'https://dummyimage.com/100x100/555/fff' },
];
ReactDOM.render(
<App data={data} />,
document.getElementById('container')
);
.gameDetails {
display: inline-block;
padding: 0.3em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>

Categories