can't get component to show up with react-images? - reactjs

I keep getting null return from this component. What am I Missing???
import React from 'react';
import Lightbox from 'react-images';
const IMAGES = [
{ src: "https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg" },
{ src: "https://c2.staticflickr.com/9/8356/28897120681_3b2c0f43e0_b.jpg" },
{ src: "https://c4.staticflickr.com/9/8887/28897124891_98c4fdd82b_b.jpg" }
];
class ImagesRow extends React.Component {
constructor(props){
super(props);
this.onClose = this.onClose.bind(this);
this.gotoNext = this.gotoNext.bind(this);
this.gotoPrevious = this.gotoPrevious.bind(this);
}
onClose(){
}
gotoNext(){
}
gotoPrevious(){
}
render(){
return (
<Lightbox
images={IMAGES}
onClose={this.onClose}
onClickPrev={this.gotoPrevious}
onClickNext={this.gotoNext}
/>
);
}
}
This results in an empty div. Is there a required prop I'm missing?
http://jossmac.github.io/react-images/#getting-started

It is not obvious from the documentation, but react-images will not render a grid/or a gallery of your images. It will only render the Lightbox component once a image is clicked.
So, in order to get what you want (which is a gallery of some kind, AND the light box component applied to images of that gallery, then you need more than just 'react-images'. You can render the images on their own, or with another gallery/grid npm library.
For example you can render an array of images with just the normal <img> tag. BUT, be sure that each image has the "onClick" set to be a function that opens the Lightbox. see below:
...
<Grid imagesArray={thumbs} onClick={this.openLightbox.bind(this)} columns={3} padding={3} />
<Lightbox
images={images}
isOpen={this.state.lightboxIsOpen}
onClickPrev={this.gotoPrevious}
onClickNext={this.gotoNext}
onClose={this.closeLightbox}
currentImage={this.state.currentImage}
/>

I believe you need isOpen. Try
return (
<Lightbox
isOpen
images={IMAGES}
onClose={this.onClose}
onClickPrev={this.gotoPrevious}
onClickNext={this.gotoNext}
/>
);

Related

Why I can't use an imported component inside a functional component in React?

I am new to React. For the code readability, instead of in-line styled button, I want to write it as a separate class component. I created a customed button 'addImageButton'and imported it to another .js file. It doesn't render the customer button when I try to use it within a functional component. How can I make the functional component be able to use the imported button? Thanks!
//addImageButton.js
import React, { Component } from "react";
class addImageButton extends Component {
render() {
return (
<div>
<button
style={{
borderStyle: "dotted",
borderRadius: 1,
}}
>
<span>Add Image</span>
<span>Optional</span>
</button>
</div>
);
}
}
export default addImageButton;
//AddNewTaskButton.js
import React, { Component } from "react";
import Modal from "react-modal";
**import addImageButton from "../addImageButton";**
class AddNewTaskButton extends Component {
constructor(props) {
super(props);
this.state = {
show: false,
};
this.setShow = this.setShow.bind(this);
this.closeShow = this.closeShow.bind(this);
this.addTaskModal = this.addTaskModal.bind(this);
}
setShow() {
this.setState({
show: true,
});
}
closeShow() {
this.setState({
show: false,
});
}
addTaskModal = () => {
return (
<div>
<Modal
isOpen={this.state.show}
onRequestClose={() => this.closeShow()}
>
**<addImageButton />**
</Modal>
</div>
);
};
render() {
return (
<div>
<button onClick={() => this.setShow()}>
<img src={addIcon} alt={text}></img>;
<span>text</span>
</button>
<this.addTaskModal className="modal" />
</div>
);
}
}
export default AddNewTaskButton;
Easier way would be to just use functional components. Also, react components should be upper case, like so:
export default function AddImageButton() {
return (
<div>...</div>
)
}
create a different component for Modal
import Modal from './Modal'
import AddImageButton from './AddImageButton'
function AddTaskModal() {
return (
<div>
<Modal> <AddImageButton/> </Modal>
</div>
)
}
then
import AddTaskModal from './AddTaskModal'
function AddNewTaskButton() {
return (
<div>
<AddTaskModal/>
</div>
)
}
I don't know your file directories, so I just put randomly.
as for your question, try to make the AddImageButton as a class and see if it renders then. If it doesn't it might be due to something else. Do you get errors? Also maybe create the AddTaskModal class separately and render it out as a component. Maybe that'll help

Dynamic Image not rendering

I want to dynamically render images, but nothing is show up. Here is the starter code that I am using from Import image dynamically in React component.
import React, { Component, Fragment } from 'react';
class Test extends Component{
constructor(props){
super(props);
this.state = {
image: "",
}
this.loadImage = this.loadImage.bind(this);
}
componentDidMount(){
this.loadImage("Test")
}
loadImage = imageName => {
import(`../assets/${imageName}.png`).then(image => {
this.setState({
image
});
});
};
render() {
const { image } = this.state;
return (
<Fragment>
hello
{image && <img src={image} alt="" />}
</Fragment>
);
}
}
export default Test;
Hello renders, but the image is no where to be seen. Any thoughts
You can add the string directly into your image state, without rendering it asynchronous. I don't think the import statement is needed. Once you have the string you could use a similar logic you have already in place with the image but instead if you are using webpack this might work:
<div
style={{
backgroundImage: `url(${image})`,
height: "106px"
}}
If you are not using webpack, than you can add the image state in the src attribute.

How to apply MathJax/KaTex to render a React component

I am making a web editor using React & SlateJS. There are LaTex code in the editor content and I want the user to see the rendered LaTex equations. MathJax and KaTex have auto-rendering feature by loading them as CDNs. Once they are loaded, the content on html body is rendered. But they are not live-rendering when I modify the content.
So I have made a button that opens a modal which renders the un-editable edior content in a smaller window, and I want the LaTex codes to be rendered in the modal.
The APP component:
import {Editor} from 'slate-react';
import ReactModel from 'react-modal';
import RenderedEditorDialog from "./RenderedEditorDialog";
class APP extends React.component {
...
render() {
return (
<div className={"editorContainer"}>
<div className={"editor"}>
<Editor
autoFocus
ref={this.ref}
value={this.state.value}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
renderMark={this.renderMarks}
renderBlock={this.renderBlock}
/>
</div>
<ReactModal
isOpen={this.state.showMathDialog}
contentLabel="Rendered content"
onRequestClose={this.handleCloseMathDialog}
>
<button onClick={this.handleCloseMathDialog}>Close Dialog</button>
<RenderedEditorDialog value={this.state.value}/>
</ReactModal>
</div>
)
}
}
RenderedEditorDialog (modal) component:
import {Editor} from 'slate-react';
class RenderedEditorDialog extends React.Component {
// eslint-disable-next-line no-useless-constructor
constructor(props) {
super(props);
}
render() {
return (
<div>
<Editor
value={this.props.value}
renderMark={this.renderMarks}
renderBlock={this.renderBlock}/>
</div>
)
}
}
My question is how I can apply MathJax/KaTex to render the content in RenderedEditorDialog component?
Thanks in advance!
KaTeX can be applied to individual DOM elements on demand, instead of all at once, by calling renderMathInElement when desired. Calling this from componentDidUpdate should do the trick:
import {Editor} from 'slate-react';
class RenderedEditorDialog extends React.Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
render() {
return (
<div ref={this.ref}>
<Editor
value={this.props.value}
renderMark={this.renderMarks}
renderBlock={this.renderBlock}/>
</div>
)
}
componentDidUpdate() {
renderMathInElement(this.ref.current, katexOptions);
}
}
I'm more comfortable with hook-based components instead of classes, which would look like this:
function RenderedEditorDialog(props) {
const ref = useRef();
useEffect(() => {
renderMathInElement(ref.current, katexOptions);
});
return (
<div ref={ref}>
<Editor
value={props.value}
renderMark={props.renderMarks}
renderBlock={props.renderBlock}/>
</div>
)
};
I'm not sure whether you want this on RenderedEditorDialog or another more specific component, but this should give you the idea. For speed, you want to apply renderMathInElement to the smallest container that contains the updated math.

How to change image source using state variable with React.js

I have an image component with the following html:
<img src={this.state.img_path} onClick={this.getNew} alt={this.state.alt} width={150} />
Initially I set the image to Blank which I import from an image:
import Blank from './images/blank.jpg';
then I use Blank to initialize my state variable.
When the image is clicked, getNew is called, where I set the state variable img_path to a relative image path:
this.setState({img_path: item.ImgPath, alt: item.alt});
The function getNew gets called without an issue and executes without an error but the image does not get displayed, just an icon and alt value. How do i do dynamic image source switch in React?
Update:
here is my class
import React, { Component } from 'react';
import Blank from './images/blank.jpg';
class myImg extends Component {
constructor(props) {
super(props);
this.state = {
img_path: Blank,
alt: 'blank',
};
this.getNew = this.getNew.bind(this);
}
getNew() {
const items = [{ItemName: 'test1', ItemImg: './images/test1.jpg'}, {ItemName: 'test2', ItemImg: './images/test2.jpg'} ];
var item = items[math.floor(Math.random() * items.length)];
this.setState({ img_path: item.ItemImg,
alt: item.ItemName });
}
render() {
return (<div>
<img src={this.state.img_path} onClick={this.getNew} alt={this.state.alt} width={150} />
</div>);
}
}
export default myImg;
I figured out the fix. I used require. At first it did not work but then I wrapped the image path state variable in ${}. Basically I changed
<img src={this.state.img_path} onClick={this.getNew} alt={this.state.alt} width={150} />
to
<img src={require(`${this.state.img_path}`)} onClick={this.getNew} alt={this.state.alt} width={150} />
that got the image to be displayed

Custom React-Bootstrap Popover

I want to create a custom react popover, based on Bootstrap Popover, just with my own design and maybe more props.
I created a new react component called MyTooltip :
import React, {Component} from 'react';
import { Popover } from 'react-bootstrap';
export default class MyPopover extends Component{
constructor(props){
super(props);
}
render() {
return (
<Popover id="popover-trigger-focus" title={this.props.title}>
{ return this.props.children }
</Popover>
);
}
}
and in my main component I tried to create a trigger:
export default class MyMainComponent extends Component{
render() {
const popoverFocus = (
<MyPopover id="tooltip-trigger-focus" title="My Title">
my text <b>my bold text</b> my text
</MyPopover >
);
return (
<div >
<OverlayTrigger trigger="focus" placement="bottom" overlay={popoverFocus}>
<Button>Focus</Button>
</OverlayTrigger>
</div>
);
}
}
But it doesn't work. The button does hide and show the popover with the right text, but the popover ignores the "placement" property and it doesn't have the fade animation.
Any help will be useful...
You've set the placement and overlay prop to the <OverlayTrigger/> element, but those belong on the Popover. You can quickly fix this by letting the popover inherit the props from the trigger element like so:
render() {
return (
<Popover id="popover-trigger-focus" title={this.props.title} {...this.props}>
{ this.props.children }
</Popover>
);
}
Here's your example with {...this.props}.
PS: You don't need to return JS in JSX (e.g. { return this.props.children }). You can just leave that out ({ this.props.children }).

Resources