reactstrap carousel html tag on variable - reactjs

good day to all. im new to react app, and i usses reactstrap for my carousel. i just copied the code from reactstrap documentation. and i want to add a html tag on the item variable. but just print the html tags on my website. how do i do it correctly?
my variable is:
const items = [
{
imageUrl: 'static/media/slide1.jpg',
idName: 'S1',
captionHeader: 'slide 1 <strong>text here</strong>',
captionText: 'slide 1 <strong>text here</strong>',
},
{
imageUrl: 'static/media/slide2.jpg',
idName: 'S2',
captionHeader: 'Slide 2',
captionText: 'Slide 2'
}
];
then i added it here:
<CarouselItem
onExiting={this.onExiting}
onExited={this.onExited}
key={item.src}
>
<div className="carouselIMG" id={item.idName} style={{ backgroundImage: `url(${item.imageUrl})` }}>
</div>
<CarouselCaption captionText={item.captionText} captionHeader={item.captionHeader} />
</CarouselItem>
this part:
<CarouselCaption captionText={item.captionText} captionHeader={item.captionHeader} />
p.s.
can you aso check my "imageUrl" is there a best way to grab the image location? atfirst i tried ../images/imagename.jpg, just like what i do when im importing js file. but it doesnt seem to located the address, so i just manually check if where the images are stored when build.
thanks in advance.

You can see that in react strap documentation the prop types are,
CarouselCaption.propTypes = {
captionHeader: PropTypes.string,
captionText: PropTypes.string.isRequired,
cssModule: PropTypes.object
};
So the captionHeader and captionText need to be strings. How ever you can give font-weight css style for this whole text.
And regarding the picking of images you may check out this SOF answer.

It sounds like you are getting the values rendered in the user view, but what you want is the values stored on a tag on the html.
Note that CarouselCaption is not html, it is a custom react component. ;)
You need to place the following code like attributes on native html tags to get them stored in html dom.
<div> captionText={item.captionText} captionHeader={item.captionHeader}> </div>
A good example is found in their github repo under demos.
https://github.com/gajus/react-carousel/blob/master/demo/src/index.js
Here you notice that they create an array of a bunch of these using map.
<div key={String(index)}>{index}</div>;
Then they render this as a child of the carousel. So you'd just put your attributes on the html. With html I can create a div like
<div thisIsACustomHTMLAnAttribute="valuesToBeStoredInTheDom"> </div>
However the equivalent in custom react component would try to either pass to the component for use or try to render it as values.
<div captionText={item.captionText}> </div>

Related

Gatsby Image inside Flickity carousel

I am creating a gatsby website that uses the flickity-react-component to display a slider with product images. I believe that I should use the gatsby image to make it load faster, but when I try it, the Image does not display (it is 0x0 pixels).
This is the code I am trying to run:
const ThirdPage = ({ data }) => {
...
function Carousel() {
return (
<Flickity
className={'carousel'} // default ''
elementType={'div'} // default 'div'
options={flickityOptions} // takes flickity options {}
disableImagesLoaded={false} // default false
reloadOnUpdate // default false
static // default false
>
<Img fluid={data.imgPrincipal.childImageSharp.fluid} alt="Mulher a lavar o cabelo com o chuveiro ecológico" />
<img src="https://placeimg.com/640/480/nature" />
<img src="https://placeimg.com/640/480/nature" />
<img src="https://placeimg.com/640/480/architecture" />
</Flickity>
);
}
The "Img" is the one using the gatsby image, the others are what I had before.
This is the result
I don't get an error when running this, I believe this might be because gatsby-image creates a div.
Can someone help me make this work? I am a beginner, so if it's something very advanced, I would appreciate an alternative ... Thank you.
Indeed, gatsby-image is not only a simple image. It creates a wrapper with a few nested div HTML structure inside to make the blur effect and the rest of the improvements.
Take a look at gatsby-image docs:
Note: gatsby-image is not a drop-in replacement for <img />. It’s
optimized for fixed width/height images and images that stretch the
full-width of a container. Some ways you can use <img /> won’t work
with gatsby-image.
It may not work with all sliders.
I've used it with other sliders that accept a nested structure inside, not only a single <img> tag such as Swiper or Slick.

Make images in a text clickable in React

I'm building a website where I get a blog post from an API call. The body of the post is just html code mixed with text, images and even objects like youtube videos (it is build with ckeditor in the back). Everything is working as expected but I would like to make images clickable. Clicking the image, would open a modal in lightbox style.
I was considering extracting all the images (if any) from the body and making a gallery at the bottom of the post. But I think that would be more elegant just making images clickable and opening the dialag without showing them twice along the post.
An example of the response:
body: "<p>this is a text with some images: <img src='path/to/image1' /> and <img src='path/to/image2' /> how to make them clickable in React?</p>"
That body is rendered this way:
<GridItem xs={12} sm={8} md={8}>
<div dangerouslySetInnerHTML={{ __html: text }} />
</GridItem>
You can use the onClick event in your image:
<img src='path/to/image2' onClick={() => {aFunction}} />
ps: if you want to, you can add a className to put a cursor:pointer too.
I think this might help you
first of all, you need to cover the content of blog post (returned HTML from API call) into one single wrapper div.
after that, you can need to get all the elements of blog post using javascript like the example below
const elements = document.getElementById("wrapper").elements
now you can iterate throw all elements in blog post including the images
elements.forEach(item => {
if (item.type == "img")
// do this
})
I will edit the second code example in a few minutes

Update dom without refresh the page in react 16

So, I've been looking for a way to render this img tag on my dom without refresh the screen. But I didn't find a definitive answer on how to do that! I mean, in a natural way, with react library and without change a lot of things.
So, when I click this div, it calls a method
<div ref={(ref) => this.refProjectImageCenter = ref} onClick={(e) => this.selectImage(e, this.refProjectImageCenter)} >
<img src="images/projects/new-account.png" alt="new account" />
</div>
And in this method, I update my state with a new img element (not sure if it's the best way to do it tho)
selectImage(e: any , el: HTMLDivElement)
{
e.preventDefault(); // This is not working
this.setState({ selected_img: <img src={el.children[0].getAttribute("src")} /> });
}
And the state will update this part of the DOM
<div className="image detail">
{this.state.selected_img}
</div>
It renders the img indeed, but the page flashes(refresh), and I want to do that asynchronously. It's possible to do that with react? If it's not, how everybody is doing it right now? Thanks a lot.
I found the problem Henry and Shubham. I was updating the css class of the main html tag:
this.refMasterDOM.classList.remove("active");
Inside the method componentWillUpdate(). I removed this line and it stopped refreshing the page with sestate command. Although I don't know why.

React - Why doesn't addEventListener work?

I am trying to create a website by using GatsbyJS, and I got stuck whenever I need to set a onClick event to toggle a class in one of my components. As a beginner with react and gatsby, I'm having a hard time to do it.
So essentially I want to make the following JS code in React/GatsbyJS:
const hamburger = document.querySelector('.burger_menur');
hamburger.addEventListener('click', function(){
this.classList.toggle('open');
});
The following code is my current code in Gatsby component. Have to say, I am using GSAP to make an animation.
This is my code:
import React from 'react';
import { Tween, Timeline } from 'react-gsap';
import '../styles/burger.scss'
const Burger = () => (
<Timeline
target={
<div className='burger'>
<div className='burger_menu'>
<div className='bar half start'></div>
<div className='bar'></div>
<div className='bar half end'></div>
</div>
</div>
}
>
<Tween from={{ opacity: '0', marginRight: '0rem' }} to={{ opacity: '1', marginRight: '5rem' }} ease="Back.easeOut" delay={2}/>
</Timeline>
);
export default Burger
Hopefully someone can help me out with this.
If you're going to go with React, don't manipulate the DOM directly.
More specifically, don't try to act directly on any part of the DOM generated by React.
Here, you're using plain DOM manipulation to attach your event to elements generated by React (also, there's a typo in your class name):
const hamburger = document.querySelector('.burger_menur');
hamburger.addEventListener('click', function(){
this.classList.toggle('open');
});
The thing is, while it may sometimes work, React will regenerate new elements for your menu when it deems it necessary, and your events listeners will be lost.
You have to do it "the React way":
...
<div className='burger'>
<div className={`burger_menu ${this.state.isOpen? ' open' : ''}`} onClick={() => this.setState({ isOpen: !isOpen })}>
<div className='bar half start'></div>
<div className='bar'></div>
<div className='bar half end'></div>
</div>
</div>
...
Don't forget to initialize your state with { isOpen: false }
Clicking the div will toggle this.state.isOpen, which is used to decide whether the class-name will be 'burger_menu' or 'burger_menu open'.
Note: There are more elegant ways to work with classlists when they get longer, but your component being simple and for the sake of clarity, a string template will more than do.
If any of this sounds confusing, please read through the official tutorial Intro To React, it's very well explained and covers everything needed here.
If you're already comfortable with this and want to know more about handling events in React, the docs has you covered once again: Handling Events

`rexxars/react-markdown` plugin usage or alternative for rendering React markdown

I'm trying to render some html, stored in a DB, and put a component inside.
It'd look like this:
import ReactMarkdown from 'react-markdown/with-html';
const inlineCode = (props) => <Gist id={props.value} />;
const source = '`7df0c9a5d794504a28bd3256b7bf5c4f` <p>asdasdasd</p><h1>title</h1>';
ReactMarkdown is used like this:
<ReactMarkdown source={source} renderers={{ inlineCode }} escapeHtml={false} />
The result is is rendered properly and the block is also, but isn't, the contents are outside of the block.
If I wrap the whole source with a <div>, the <Gist/> is rendered as text and <p>/<h1> are rendered properly.
What am I missing? I'm trying to store html with custom components inside, <Gist/> is just an example. Suggestions for a (more) suitable library are also welcome. Example ideal source I'd like to store in a db and then render in a React component:
<div>
<p>
<CustomReactComponent/>
<br/>
test
</p>
<Gist/>
</div>
Okay I found this lib: https://github.com/probablyup/markdown-to-jsx
If your source looks like:
const source = `<gist id="yourIdHere" /> <h1>asdasdasd</h1>`;
<Markdown
options={{
overrides: {
gist: {
component: renderGist,
},
},
}}
>
{content}
</Markdown>
It renders both the <Gist> and the normal <h1> as <h1. Paragraph tags seem to be automatically added if you add line breaks and something like # Title is also automatically wrapped.
<Gist> in source is converted to lowercase, so it'd only matter for the overrides object (lowercase again). Handles all my custom stuff and html predictably.

Resources