Simplest way to use onClick to render <img> in React? - javascript

Im looking for a way to display an image when a button is toggled on. It seems like a simple enough task, and would help me greatly to understand how to do it. I have tried something like this, but it does not render anything.
This is the function that returns the svg image:
import dfElement from '../vectors/dfElement.svg';
function renderElement(){
return <img src={dfElement}/>
}
This is the class that calls the function to return svg:
class DF extends Component {
render() {
return (
<div >
<div >
<button onClick={this.renderElement}>df</button>
</div>
</div>
);
}
}
export default DF

I've used Functional Component with useState().
It's a simpler way to make a component.
ref >
https://en.reactjs.org/docs/hooks-intro.html
function App(){
const [toggle, setToggle] = React.useState(false);
return (
<div>
<button onClick={()=>setToggle( (prev) => (!prev) )}>Toggle!</button>
<br/>
{
toggle && <img src='https://2.imimg.com/data2/LQ/QV/MY-/teddy-small-size-500x500.jpg' />
}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root" />

Related

React pass ref throw functional components in different levels

I would like to scroll to menu element in a page.
I have the menu component which is not a parent of components to which I would like to scroll.
I have found this post that describe a similar problem
Passing ref to a child We want the ref to be attached to a dom element, not to a react component. So when passing it to a child
component we can't name the prop ref.
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp> } ```
Then attach the ref prop to a dom element. ```jsx const ChildComp =
(props) => {
return <div ref={props.refProp} /> } ```
Here's my app structure
Menu component:
const MenuApp = () => {
return (
<div>
<div className="desktop-menu">
<div className="menu-item a-propos">
<p className='button'>Me découvrir</p>
</div>
<div className="menu-item competences">
<p className='button'>Compétences </p>
</div>
<div className="menu-item experiences">
<p className='button'>Experiences</p>
</div>
<div className="menu-item formation">
<p className='button'>Formation </p>
</div>
</div>
</div>
)
}
The parent is app component
<div className="App">
<div className="hero">
<HeaderApp />
<ApprochApp />
</div>
<Apropos />
<Competences />
<Experiences />
<Formation />
<Recom />
<Contact />
<Footer />
</div >
I would like that mu menus scrolls to the react components in the main App component
So how can I passe the reference from the menu component to the app and use it in components to scroll ?
I do not understand your problem completely though. However, one thing I can see from your question is that you're not forwarding the ref properly.
What you need in this case is forwardRef.
Basically, what you need to do is to create the childComponent as something like this:
const childComponent = React.forwardRef(({...otherProps}, ref) => {
return (<><div ref={ref}>Component content </div></>)
})
Where you need to use the component all you need to do is this:
const parentComponent = () => {
const reveiwsRef = React.useRef("");
return (
<div>
<childComponent ref={reviewsRef} />
</div>
);
}
You can find more info about this on the react documentation: Forwarding-Refs
I have hope this helps though

How do I pass button click event if I am using this.props.children in React

I have created a react component which is the modal wrapper only. The content is passed by this.props.children. In the content I have a button, clicking it should pass an event to the parent.
Here is the render part of modal wrapper code
<div class="modal-container-backdrop">
<div class="modal-container-overlay" onClick={this.onOverlayClick}>
<div class="modal-container-content" style={{padding: this.props.isCloseable ? '30px 20px' : '0px 0px' }} onClick={this.onContentClick} style={{width: this.props.modalWidth ? this.props.modalWidth+'px' : '320px'}}>
{this.props.isCloseable ? <div class="modal-container-close-img" onClick={this.onCloseImgClick}></div> : null }
{this.props.children}
</div>
</div>
</div>
It is not so different just passing a callback handler without using {this.props.children}. Am I missing something?
class App extends React.Component {
handleClick = () => alert("clicked");
render() {
return (
<div>
<Child>
<button onClick={this.handleClick}>Click</button>
</Child>
</div>
);
}
}
class Child extends React.Component {
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You need do it using React.children
{React.Children.map(children, child => React.cloneElement(child, {
...this.pros,
onClick: () => console.log("click")
}), null)}
This a really good post about childrens on React:
https://mxstbr.blog/2017/02/react-children-deepdive/

How to add odd/even class to wrapping divs

I'm trying to build a page where I want to wrap each component inside a div which either has an "odd" or "even" class so that I can set different background-colors. I'm pretty new to gatsby and react so I wonder how to do that?
I followed the instructions how to set up an gatsby-project here and this is what I got so far:
index.js:
const IndexPage = () => (
<div className="page-container">
<component-1 />
<component-2/>
<component-3/>
<component-4/>
<component-5/>
</div>
)
export default IndexPage
what I want is something like this
const IndexPage = () => (
<div className="page-container">
<div className="odd">
<component-1 />
</div>
<div className="even">
<component-2 />
</div>
<div className="odd">
<component-3 />
</div>
<div className="even">
<component-4 />
</div>
</div>
)
export default IndexPage
I just called my components silly names for display reasons...
How can I achive this?

How do i execute alert() in parent component after onClick in child component

In here, i'm passing data from child to parent and i am able to pass it through but i want alert function to execute only after onClick event is triggered in the child component but it is executing everytime onSubmit event is fired, it looks like there is a requirement of some life cycle method in order to make it work but i'm not getting it. Can someone help me with this please
Parent
onList(list) {
alert(list);
}
render() {
return (
<div>
<form>
<input type='textarea'
onKeyPress={this.handleSubmit}
/>
<Child {...this.state} sendList={this.onList}/>
</form>
</div>
)
}
Child
{
this.props.listArr.map((list,index) => {
return(
<div key={index}>
<li>{list}
<div>
<button className="btn btn-primary btn-xs glyphicon glyphicon-pencil" onClick={this.props.sendList(list)} />
</div>
</li>
</div>
)})
}
change to:
<Child {...this.state} sendList={(...args) => this.onList(...args)} />, to preserve the function context.
then, in Child just call that method as this.props.sendList()
You can use event.preventDefault() on button click so the form doesn't get submitted.
const Child = ({ sendList, list }) =>
<div>
<button onClick={(event) => sendList(event, list)}>Click</button>
</div>
class Parent extends React.Component {
constructor() {
super()
this.onList = this.onList.bind(this)
}
onList(event, list) {
event.preventDefault()
console.log('onList', list)
}
render() {
return (
<form>
<Child sendList={this.onList} list={[]} />
</form>
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Render array data in class i react

I have to make a card.
For that I need to make 3 components.
First for Card Header
Second for Card Description and
Third for main Card that will give values to both components.
In my Card class I want to display the array data. I have no idea how to do that.
I believe I should use map() but I do not understand how.
My structure should be like Card header1 with Card description1 then Card header2 with Card description2.
<!Doctype html>
<html>
<head>
<title>React Cards</title>
<link rel="stylesheet" href="screen1.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
<script type="text/jsx">
class Header extends React.Component { render () { return (
<div className='t1'>
<h1>{this.props.text}</h1>
</div>
) } } class CardDesc extends React.Component { render () { return (
<div className='t2' id='this.props.id'>{this.props.text}</div>
) } } class Card extends React.Component { render () { return (
<div className='t3'>
<Header text="this.props.head" />
<CardDesc text="this.props.des" />
</div>
) } } var cardContent = [ {head:'Header one',des:'000'}, {head:'Header two',des:'001'},
{head:'Header three',des:'002'}, {head:'Header four',des:'004'}, {head:'Header
five',des:'005'}, {head:'Header six',des:'006'} ]; ReactDOM.render(
<Card />, document.getElementById('root'))
</script>
<div id="root"></div>
</body>
</html>
When you want to pass a variable as props, don't use quotes, instead use {}, so change:
<Header text="this.props.head"/>
<CardDesc text="this.props.des" />
To:
<Header text={this.props.head}/>
<CardDesc text={this.props.des} />
Now, you can simply render your cards like so:
ReactDOM.render(
<div>
{cardContent.map(cardItem => <Card head={cardItem.head} des={cardItem.des} />)}
</div>
, document.getElementById('root'))
As you can see, a root element (div in this case) is required for the render function.
Another method would be to create a CardList component, and render that, instead of having the map in ReactDOM.render.
I think multiple rendering to the root element is bad idea, you can try create new component like App or whatever, end map your card components into it.
Look at this

Categories

Resources