const HiContainer => (props) {
render{
return(
<h1>Hi {this.props.greet}</h1>
)
}
}
ReactDOM.render(
<HiContainer greet="hi"/>
document.getElementById('root')
);
What's wrong with this code? It's hard to debug I can't see which lines has problem in the console.
Also when do I need to use constructor?
You have some syntax errors, should be
const HiContainer = (props) => {
return(
<h1>Hi {props.greet}</h1>
)
}
and can be simplify to:
const HiContainer = props => <h1>Hi {props.greet}</h1>
You may need to learn from the basics, this is arrow function:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Problem is, you are using the arrow function in a wrong way.
It should be like this const HiContainer = () => {}.
Try this it will work:
const HiContainer = (props) => {
return(
<h1>Welcome {props.greet}</h1>
)
}
ReactDOM.render(
<HiContainer greet="hi"/>,
document.getElementById('app')
);
constructor is required when you use stateful components, and store the information in state variable, since you are using stateless components, constructor is not required.
Check jsfiddle for working example: https://jsfiddle.net/ej2szg3a/
Check this for Stateless Function Components: https://www.reactenlightenment.com/react-state/8.4.html
Seems like you're using functional component, which handles render method automatically.
The code should be:
const HiContainer = (props) => (
<h1>Hi {props.greet}</h1>
)
If you want to add lifecycle methods to the component, you need to convert it to class component.
Related
I use React + styled and my question is about the following code
<MobileButton
onClick={props.handleMobileDropdownElementClicked}
padding={isSmallDevice ? 1 : 0}
>
Name
</MobileButton>
Is there a way to generalise this component to write like this without having props and onclick()? like the following code.
<MobileButton>
Name
</MobileButton>
I was just curious if there is things in react or styled component that could do that if we are repeating the same component with the same props/onclick function.
Thank you
Sure, you can make a new component that doesn't require said props. But you'll still have to pass the props when creating that component initially.
For example:
const YourComponent = (props) => {
const NewMobileButton = (newProps) => {
return (
<MobileButton
onClick={props.handleMobileDropdownElementClicked}
padding={isSmallDevice ? 1 : 0}
>
{newProps.children}
</MobileButton>
)
}
return (
<>
<NewMobileButton>1</NewMobileButton>
<NewMobileButton>2</NewMobileButton>
</>
)
}
I'm having trouble understanding the spread operator when I want to pass all other props to a component.
Any help would be appreciated.
import React, { Fragment } from "react";
import SiteCard from "./SiteCard";
const SiteList = ({ sites }) => {
return (
<Fragment>
{sites.map((site) => {
return (
<SiteCard
key={site.login.uuid}
image={site.picture.large}
firstName={site.name.first}
lastName={site.name.last}
city={site.location.city}
country={site.location.country}
sensors={site.dob.age}
otherSiteProps={...site} // how can I pass the site props here?
/>
);
})}
</Fragment>
);
};
export default SiteList;
You are almost there with the solution.
You need to pass it as otherSiteProps={{...site}}.
This is if you want to pass site as an object to otherSiteProps property of SiteCard.
If you want to spread site and have multiple props for component SiteCard you do it like this:
<SiteCard
key={site.login.uuid}
image={site.picture.large}
firstName={site.name.first}
lastName={site.name.last}
city={site.location.city}
country={site.location.country}
sensors={site.dob.age}
{...sites}
/>
This in case that sites is an object. If site is an array, this wont work.
You just need to write:
<SiteCard
key={site.login.uuid}
image={site.picture.large}
firstName={site.name.first}
lastName={site.name.last}
city={site.location.city}
country={site.location.country}
sensors={site.dob.age}
{...site} // how can I pass the site props here?
/>
But wait, why you're making so complicated? You can just use:
<SiteCard {...site} />
Now, in your SiteCard component use required props.
And if I were you, I would not have separated SiteCard component for this scenario. I would just write:
{sites.map((site) => {
return (
// everything here I will utilize in html.
);
})}
I am trying to call PopupDialog.tsx inside Content.tsx as a sibling of Item.tsx.
Previously PopupDialog.tsx is called inside C.tsx file but due to z index issue i am trying to bring it out and call it in Content.tsx
Is it possible to somehow pass the whole component(popupDialog and its parameters) in Content.tsx so that i could avoid passing back and forth the parameters needed for popupdialog in content.tsx.
Code in C.tsx where PopupDialog component is called.
const C = (props: Props) => (
<>
{props.additionalInfo ? (
<div className="infoButton">
<PopupDialog // need to take this code out and want to add in Content.tsx
icon="info"
callback={props.callback}
position={Position.Right}
>
<div className="popuplist">{props.additionalInfo}</div>
</PopupDialog>
</div>
) : (
<Button className="iconbutton"/>
)}
</>
);
Content.tsx where i would like to call PopupDialog.tsx with its parameters
const Content = (props: Props) => {
const [componentToRender, docomponentToRender] = React.useState(null);
const [isAnimDone, doAnim] = React.useState(false);
return (
<div className="ContentItems">
<PWheel agent={props.agent} />
{isAnimDone && (
<>
<Item {props.agent} />
{componentToRender &&
<PopupDialog/> //want to call here with all its parameters to be passed
}
</>
)}
</div>
);
};
Folder Structure
App.tsx
->ViewPort.tsx
->Content.tsx
->PWheel.tsx
->Item.tsx
->A.tsx
->B.tsx
->C.tsx
{props.additionalinfo &&
->PopupDialog.tsx
->PopupDialog.tsx
So if I understand the question correctly you want to pass one component into another so that you can use the properties or data of the passed componenet in your current component.
So there are three ways to achieve this.
1)Sending the data or entire component as prop.This brings disadvantage that even though components which don't require knowledge
about the passed component will also have to ask as a prop.So this is bascially prop drilling.
2)The other is you can use context api.So context api is a way to maintain global state variale.so if you follow this approach you don't need to pass data or componenet as props.Wherever you need the data you can inport context object and use it in componenet.
3)Using Redux library.This is similar to context api but only disadavantage is that we will have to write lot of code to implement this.Redux is a javascript library.
Let me know if you need more info.
You need to :
<>
<Item {props.agent} />
{componentToRender &&
<PopupDialog abc={componentToRender} /> //you must call in this component, in this case i name it is abc , i pass componentToRender state to it
}
</>
and then PopupDialog will receive componentToRender as abc, in PopupDialog , you just need to call props.abc and done .
If you need to know more about prop and component you can see it here
I think what you want to use is Higher-Order-Components (HOC).
The basic usage is:
const EnhancedComponent = higherOrderComponent(WrappedComponent);
Below is such an implementation that takes a component (with all its props) as a parameter:
import React, { Component } from "react";
const Content = WrappedComponent => {
return class Content extends Component {
render() {
return (
<>
{/* Your Content component comes here */}
<WrappedComponent {...this.props} />
</>
);
}
};
};
export default Content;
Here is the link for higher-order-components on React docs: https://reactjs.org/docs/higher-order-components.html
Make use of
useContext()
Follow this for details:
React Use Context Hook
Hi I have some sort of the following code:
class First extends Component {
constructor(props){super(props)}
myfunction = () => { this.card //do stuff}
render() {
return(
<Component ref={ref => (this.card = ref)} />
)}
}
Why is it not possible for me to access the card in myfunction. Its telling me that it is undefined. I tried it with setting a this.card = React.createRef(); in the constructor but that didn't work either.
You are almost there, it is very likely that your child Component is not using a forwardRef, hence the error (from the React docs). ref (in a similar manner to key) is not directly accesible by default:
const MyComponent = React.forwardRef((props, ref) => (
<button ref={ref}>
{props.children}
</button>
));
// ☝️ now you can do <MyComponent ref={this.card} />
ref is, in the end, a DOMNode and should be treated as such, it can only reference an HTML node that will be rendered. You will see it as innerRef in some older libraries, which also works without the need for forwardRef in case it confuses you:
const MyComponent = ({ innerRef, children }) => (
<button ref={innerRef}>
{children}
</button>
));
// ☝️ now you can do <MyComponent innerRef={this.card} />
Lastly, if it's a component created by you, you will need to make sure you are passing the ref through forwardRef (or the innerRef) equivalent. If you are using a third-party component, you can test if it uses either ref or innerRef. If it doesn't, wrapping it around a div, although not ideal, may suffice (but it will not always work):
render() {
return (
<div ref={this.card}>
<MyComponent />
</div>
);
}
Now, a bit of explanation on refs and the lifecycle methods, which may help you understand the context better.
Render does not guarantee that refs have been set:
This is kind of a chicken-and-egg problem: you want the component to do something with the ref that points to a node, but React hasn't created the node itself. So what can we do?
There are two options:
1) If you need to pass the ref to render something else, check first if it's valid:
render() {
return (
<>
<MyComponent ref={this.card} />
{ this.card.current && <OtherComponent target={this.card.current} />
</>
);
}
2) If you are looking to do some sort of side-effect, componentDidMount will guarantee that the ref is set:
componentDidMount() {
if (this.card.current) {
console.log(this.card.current.classList);
}
}
Hope this makes it more clear!
Try this <Component ref={this.card} />
I am trying to pass two argument using props in ImageText component.
I am not sure if it is right method or I have to create a map and then pass it.
import React, { PropTypes, Component } from 'react'
const ImageText = () => (
<div className="img-with-text">
<img className="img" src={props.imageUrl} />
<p className="txt">{props.imageText}</p>
</div>
);
export default ImageText;
Calling this component from another as follows
<ImageText imageUrl="/js.com" imageText="food"/>
But is throwing error as
Uncaught (in promise) ReferenceError: props is not defined
at ImageText
In your case issue with you are using "Arrow functions" which needs to pass params inside brackets
const ImageText = () => (
Should be
const ImageText = (props) => (
Now
let props = {
imageUrl:"/js.com",
imageText:""food""
}
<ImageText {...props} />
Access inside ImageText like
{props.imageUrl} or {props.imageText}
When you define your component like that, you need to pass your props as parameters to the anonymous function:
const ImageText = ({imageUrl, imageText}) => (
... rest of the code ...
);
When using a functional component (when you don't use a class) you must pass the props as an argument into to the function.
You can pass as many props add you need into a component.
const ImageText = (props) => (...
If using a standard component (as a class) you would call a prop with
this.props
Passing down multiple props in reactJS can be done using either of following ways:
// in App.js
<Modal post= {postProps} user={userDetails}/>
// in Modal.js
const Modal = (props) => {
const title = props.post.title
const username = props.user.username
// rest of the code..
}
in above example props (in Modal.js) forms an object with keys named post and user, thus you can access them like objects.
Another way would be:
// in App.js
<Modal post={postProps}/>
// in Modal.js
const Modal = ({post}) => {
const title = post.title
// rest of the code..
}
in this example post object has been imported explicitly in Modal.js
Final Remark : With first approach it gets very clear looking at your code that what has been passed down as props from parent element and might be clear to read.
While with second approach i argue that, it is better to use in scenarios where its just one prop to pass, since you don't have to write props. everytime
you are passing the props to dump component. it's not react component. pass the props to dump as function argument.
> import React, { PropTypes, Component } from 'react'
>
> const ImageText = ({imageUrl, imageText}) => (
> <div className="img-with-text">
> <img className="img" src={imageUrl} />
> <p className="txt">{imageText}</p>
> </div> );
>
> export default ImageText;
Creating:
const ImageText = ({ imageUrl, imageText }) => (
<div className="img-with-text">
<img className="img" src={imageUrl} />
<p className="txt">{imageText}</p>
</div>
);
export default ImageText;
Using; when you have already defined imageUrl and imageText somewhere before the return keyword:
<ImageText {...{imageUrl, imageText}}