How to include s3image inside ReactJs card - reactjs

I'm working on a photo sharing app using reactJ hosted on AWS.
Everything works fine but I'm struggling to have some style for images.
Basically I have this piece of code
const PhotosList = React.memo((props) => {
const PhotoItems = (props) => {
return props.photos.map(photo => {
return (
<S3Image
key={photo.thumbnail.key}
imgKey={'resized/' + photo.thumbnail.key.replace(/.+resized\//, '')}
level="private"
/>
)
}
);
}
return (
<div>
<Divider hidden />
<PhotoItems photos={props.photos} />
</div>
);
})
What I'm trying to do is to use Card component from react semantic-ui to display pictures from S3 and I have no idea how to do it.
I was thinking to have something like from s3image to store values into a map and then iterate over and display the image using Card component. I don't know if this is possible and if so, how to do it.
I appreciate any help.
Thanks.
C.C.

if you pass an array of s3 images source as a props you can use the card component like this:
const PhotosList = React.memo(props => {
return props.photos.map(photo => (
<Card>
<Image src={photo} wrapped ui={false} />
</Card>
))
})
If you need the card to be of same height use the cards element instead to group them together.

Related

how to make only one video play at a time using react player

I have an array of react player components with different videos I want to play. Right now they can all play at the one time but I want to be able to make it so that only 1 can play at a time so if one is clicked to play the others are all paused but i am not too sure how to go about that and could do with some help. I have a play state created but I am not too sure what to do with it to achieve the outcome I want.
here is my code:
I have my main component here:
const videos = data.map((item) => {
return <Playlist url={item.url} id={item.id} />;
});
return (
<div className="sidebar-container" style={styles.container}>
<button className="add-playlist" onClick={(props) => addPlaylist()}>
Add New Playlist
</button>
<p>sidebar for now!</p>
{videos}
</div>
);
Here is the code for my playlist component right now which is what the videos array is made up of:
const [play, setPlay] = useState(false);
return (
<div className="playlist-container">
<ReactPlayer url={props.url} id={props.id} playing={play} />
</div>
);
}
Does anyone know what i can do to achieve my desired outcome?
How about using a unique ID to determine which state the "play" button applies to? Something like this:
const [play, setPlay] = useState(null);
return (
<div className="playlist-container">
<ReactPlayer url={props.url} id={props.id} playing={play === props.id} />
</div>
);
}
where the corresponding "Play" button has an onClick function to setPlay(playerId)?

React is not dynamically loading images

I am trying to dynamically load images in a map function but it won't return anything.
I can get it to load a single image if I import it at the top of the page and hardcode the src but I have tried every solution I can find to do it dynamically and none of them work.
Here is what the code looks like. I am passing props with the title of the PNGs but nothing will load.
const Project = (props) => {
const proj = props.proj
return (
<div >
{proj.map(({title, id}) =>{
return(
<div>
<div className="..." key={id}>
<img
src={require(`../Assets/${title}.png`).default}
alt={`Image of ${title} hompage`}
className='object-cover'
/>
</div>
</div>
)
})}
</div>
)
}
export default Project;
The app was set up with create react app. I tried setting up a library but it didn't load the images either.

Adding onClick prop to children using cloneElement

I'm trying to create an image gallery component which displays small thumbnail images and a larger image 'preview'. The preview is replaced with the currently selected thumbnail.
The component allows any number of thumbnails to be passed in as children, and then an onClick prop is added to each thumbnail using cloneElement. This is working fine and I can see the new prop in the console, but nothing happens once the image is clicked. Here's my code so far:
Parent
<Gallery>
{gallery.map((thumbnail) => {
return (
<Image fluid={thumbnail.asset.fluid} />
);
})}
</Gallery>
Child
const Gallery = (props) => {
const [thumb, setThumb] = useState({
preview: null,
});
const thumbnails = React.Children.map(props.children, (child) =>
React.cloneElement(child, {
onClick: () => {
console.log("Clicked!")
setThumb({
preview: child.asset.fluid,
});
},
})
);
return (
<section>
<div className={preview}>
<Image fluid={preview} />
</div>
<div className={thumbnails}>
{thumbnails}
</div>
</section>
);
};
export default Gallery;
I'm not sure why I'm not getting any response (even in the console) when the thumbnails are clicked.
This is my first time using React so apologies if this is a terrible method, please let me know if there's a simpler/better way.
I was able to solve this issue by wrapping the <Image> component in a <div> as recommended by Nadia Chibrikova:
Parent
<Gallery>
{gallery.map((thumbnail) => {
return (
<div>
<Image fluid={thumbnail.asset.fluid} />
</div>
);
})}
</Gallery>

How to use a variable (a URL saved as a string) from another component?

Question: How can I use different URLs from different components in a third component as one ?
I am learning React.js and I would like to make multiple pages. This is an example project for learning purposes. There is one page where I can see the images and info of TeamA and there is another page where I can see the images and info of TeamB.
In order to avoid duplicates, I want to separate small components. I have a Card component which displays the image of team members with name and info. I want to use this one Card component for the page TeamA and also for the page TeamB.
The only difference now is the URL for the images - there is 1 URL for TeamA and one for TeamB. It should change accordingly.
I hope I could describe the problem. Please see the code examples below.
I appreciate your help. Have a nice day!
1st Component which has a unique URL for images:
const TeamA = ({id}) => {
const exampleImages = `https://url`;
return (
<div>
<Teams>
<Card teamImg={exampleImages}/>
</Teams>
</div>
);
}
2nd Component which also has a unique URL for images:
const TeamB = ({id}) => {
const exampleImagesB = `https://url`;
return (
<div>
<Teams>
<Card teamImg={exampleImagesB}/>
</Teams>
</div>
);
}
The Component that displays the information of the Team component (above). In this component, I want to use the URLs from the other components and add it to the img tag.
const Card = ({ name, email, id, teamImg }) => {
return (
<div className='tc'>
<img alt='image' src={`${teamImg}`}/>
<div>
<h2>{name}</h2>
<p>{info}</p>
</div>
</div>
);
}
You can make team a functional component of it's own:
const Team = ({id, imageUrl}) => {
return (
<div>
<Teams>
<Card teamImg={imageUrl}/>
</Teams>
</div>
);
}
Then you can pass imageUrl into your teams at a higher level without writing them out as separate components each time.
For example if you have your different urls as an array, this could be the component above team:
const AllTeams = () => {
const images = [{ id: 1, url: 'url1' }, { id: 2, url: 'url2' }];
return (
<>
{ images.map(image => <Team key={image.id} imageUrl={image.url} />) }
</>
);
}

If statement which determines which React element to be rendered, weird behaviour

I created a Sprite component which takes in 'icon' as a prop and determines which svg to render but I'm experiencing some weird behaviour.
I've had to resort to this method because I haven't been able to find a way to work with svg's (how to change their fill color!)
const Sprite: React.SFC<ISpriteProps> = (props: ISpriteProps) => {
const color = props.color || '#ACACAC'
let icon
if (props.icon === 'pin') {
icon = <Pin color={color} />
} else if (
props.icon === 'profile'
) {
icon = <Profile color={color} />
}
return (
<React.Fragment>
{icon}
</React.Fragment>
)
}
export default Sprite
Using the <Sprite/> in my <Navigation/> component like so
<Nav styles={this.state.styles}>
<ProfileIcon onClick={this.onProfileSelected}>
<Sprite icon='profile'
color={this.state.viewing === 'profile' ? '#5A4DB2' : ''} />
</ProfileIcon>
<LogoIcon onClick={this.onLogoSelected}>
<h1>
<img src={logo} alt="zestly" />
</h1>
</LogoIcon>
<MessagesIcon>
<img src={chat} onClick={this.onMessageSelected}
alt="messages" />
</MessagesIcon>
</Nav>
and in my <CardBlock/> component like so
const Card: React.SFC<{}> = (place) => {
return (
<CardOuter>
<CardPhoto>
<span>
<Sprite icon='pin' color='#fff' />Fitzroy</span>
</CardPhoto>
<CardDetails>
<div>
<h3>Vegie bar</h3>
<h4>7:00pm</h4>
</div>
<ProfileIcons />
</CardDetails>
</CardOuter>
)
}
For some reason the icon prop I choose to pass in to the Navigation component Sprite is determining what is rendered for the Sprite's in CardBlock as well.
E.g if I make it 'profile' in Navigation it will make all sprites render the profile icon for Sprite as well even though I specifically pass in 'pin'. If I switch it to 'pin' in Navigation, all CardBlock sprites will render the pin icon.
I don't understand, is this some weird React render quirk?
EDIT: So I thought it was something to do with stateless functional component rendering so I changed Sprite to a Component
class Sprite extends React.Component<ISpriteProps, {}> {
public render() {
const color = this.props.color || '#ACACAC'
const icons = {
'profile': Profile,
'pin': Pin
}
const ActiveIcon = icons[this.props.icon]
return (
<ActiveIcon color={color} />
)
}
}
Still no love, it's rendering ALL of them as profile icons if I pass 'profile' as icon prop to Sprite in Navigation component.
EDIT: Solved. It was something wrong with the svg's
you could use classnames library to select what class should be added to React element, including svg. And in css you give fill rule that you want. https://github.com/JedWatson/classnames

Resources