Try to call a component inside a component - React - reactjs

So I started with React and I have these two Components.
In the first component I want to iterate an array of objects with the map() function (which works) and call the other component that for now just returns a simple h1 tag.
Well, nothing is been called and there is no error in the console.
I believe the problem is in the return sentence in the renderAvatarData()
(if I do console.log after the return sentence it seems to not get there but if the console.log is before the return it invokes)
HomePageBoxesData.js
import React, { Component } from 'react';
import AvatarDetails from './AvatarDetails';
class HomePageBoxesData extends Component{
constructor(props) {
super(props);
};
renderAvatarData(){
this.props.data.map(data => {
return <AvatarDetails data={data}/>
});
}
render(){
return(
<div>
{this.renderAvatarData()}
</div>
);
}
};
export default HomePageBoxesData;
AvatarDetails.js
import React, { Component } from 'react';
class AvatarDetails extends Component{
constructor(props) {
super(props);
};
render(){
return(
<h1>Hello World</h1>
);
}
};
export default AvatarDetails;

Issue is in renderAvatarData() method, you forgot to use return with map, Use this:
renderAvatarData(){
return this.props.data.map((data)=>{
return <AvatarDetails data={data}/>
});
}
Since you just want to return the Component, you can directly write it like this:
renderAvatarData(){
return this.props.data.map(data => <AvatarDetails data={data} /> );
}

i agree with Mayank Shukla but i usually use this method in this case:
render() {
return(
<div>
_.map(this.props.data, function(value, key){
return(
<AvatarDetails key={key} data={value} />
)
})
</div>
i am not sure if there is one better than the other

Related

How can I pass data from a component array to an another component with props?

I need a little help. I'm working on a project that uses Class Components in React and I got stuck with a issue.
How can I pass datas using props?
For example, imagine that I have one Component that have an array in the state:
import React,{Component} from "react";
class CarList extends Component{
constructor(props){
super(props);
this.state = {
carList: ['Jeep', 'Kwid','HB20','Ônix', 'Prisma', 'Gol quadrado']
}
}
render(){
return(
<div>
</div>
);
}
}
export default CarList;
And now I have to call this array in a Option Tag inside a Select Tag.
Let's imagine this component Bellow:
import React from "react";
import { Component } from "react";
import CarList from "./components/Datas";
class App extends Component{
render(){
return(
<div>
<p>I got it! Here is the car list:</p>
<select>
{this.state.CarList.map( (item,x)=>{
return(
<option key={x}>{item}</option>
)
})}
</select>
</div>
)
}
}
export default App;
This piece of code does not work.
the console.log says: "Uncaught TypeError: this.state is null"
I know that I could create a div with my datas and call with , but I have to use props to pass the datas between the Components.
How can I create a callback function using props to resolve this?
Hi!
I tried to call using this.state, but I got "this.state is not defined"
To pass your data as a props you have to pass it to your child component like this from your parent component :
class ParentComponent extends React.Component {
state = {
carList: [],
};
constructor(props) {
super(props);
this.state = {
carList: ['Jeep', 'Kwid', 'HB20', 'Ônix', 'Prisma', 'Gol quadrado'],
};
}
render() {;
return (
<div>
<ChildComponent carList={this.state.carList || []} />
</div>
);
}
}
and then it is accessible in your child component with this.props.
you can use this props in child component like this:
class ChildComponent extends React.Component {
render() {
return (
<div>
{this.props.carList.map((cars, index) => {
return (
<span key={index}>
{cars}
<br />
</span>
);
})}
</div>
);
}
}
Edit -
if you want to see source code : https://stackblitz.com/edit/react-ts-ddcylu?file=Parent.tsx

Props is not showing something on the screen

I am trying to show the number 0 on the screen using props. However nothing shows on the screen and I am not sure why. This is the code:
import React,{Component} from 'react';
import Toolbar from './Toolbar.js';
class Counter extends Component {
constructor(props) {
super(props);
this.state ={
counter:0
}
};
render() {
return(
<div>
{this.state.counter.map(count=>(
<Toolbar count={count}/>
))}
</div>
)
}
};
export default Counter;
And this is where I called it
<div className="toolbar__cart">
<span>{props.count}</span>
<img src="Images/basket.png" alt="Basket" width="40"/></div>
I don't think the map function is applicable here since the value of counter is an integer and not an array. See here for more info on the map function.
If you just want your Toolbar component to display the value of this.state.counter, you could use this:
return(
<Toolbar count={this.state.counter}></Toolbar>
)
And then your Toolbar component would use that counter value like this:
function Toolbar(props) {
return (
<div>
<span>{props.count}</span>
<img src="Images/basket.png" alt="Basket" width="40"/>
</div>
)
}
You are using map function incorrectly.
.map is a function used along with an array
Check out : https://www.w3schools.com/jsref/jsref_map.asp
Correct Code :
render() {
return (
<div>
<Toolbar count={this.state.counter} />
</div>
);
}
You can checkout full code here : https://codesandbox.io/s/naughty-lederberg-hb4wp?file=/src/App.js:203-309
counter.map map function for Arrays - sample
import React,{Component} from 'react';
import Toolbar from './Toolbar.js';
class Counter extends Component {
constructor(props) {
super(props);
this.state ={
counter:[0,1,2]
}
};
render() {
return(
<div>
{this.state.counter.map(count=>(
<Toolbar count={count}/>
))}
</div>
)
}
};

Pass dynamic value to higher order component

In my code I have to use the same lines of code at different places. So i thought that's the right time to put this code into a kind of base class. I've read about Higher-Order Components which seems to be the way to go and following some examples i ended up with the following code, which is not working. I've tried something around but was not able to get it work.
My HOC:
export interface HocProps {
DynamicId: string
}
const withDiv = (hocProps) => (BaseComponent) => {
return class extend React.Component {
render() {
return (
<div id={ hocProps.DynamicId }>
<BaseComponent />
</div>
);
}
}
}
export default withDiv;
A component to be wrapped by the div:
import withDiv from './MyHoc';
class MyComponent extends React.Component {
render() {
return (
<h3>Some content here</h3>
);
}
}
export default withDiv({ DynamicId: <dynamic value> })(MyComponent);
Another component, that uses MyComponent:
import MyComponent from './MyComponent';
export class OtherComponent extends React.Component {
render() {
return (
<div>
... Some content here ...
<MyComponent DynamicId={ 'id123' } />
</div>
);
}
}
I'd like to pass an id to in OtherComponent. Then in MyComponent this id has to be passed to the HOC as , which is not working. I only can pass static values to the HOC.
I'm new to react and I think i've made same mistake(s).
So my question is: What am i doing wrong and how is it done right?
Maybe there is another/better way for this?
Thanks in advance.
Edit:
I would expect this result:
<div>
... Some content here ...
<div id='id123'>
<h3>Some content here</h3>
</div>
</div>
There are two ways you can use HOCs according to your implementation.
I have created a sandbox, which will help you understand how to use HOCs.
One way is to extract your props out const hocWrapper = Component => props => { // return NewComponent and call it too }. Here you have to call your component while returning.
Other way is to destructure or use the props inside hocWrappers. const hocWrapper = Component => { // return NewComponent, you will receive props inside the newComponent and do what you wish}
Try this
const withDiv = (BaseComponent) => {
class CompWithDiv extends React.Component {
render() {
return (
<div id={this.props.DynamicId}>
<BaseComponent />
</div>
);
}
}
return CompWithDiv ;
}
export default withDiv;
Im not sure how you pass the dynamic values and whats wrong with it. but, you can just create your component like
export interface MyCustomProps {
customProp: string;
}
export interface MyCustomState {
something: string;
}
class MyComponent extends React.Component<MyCustomProps, MyCustomState>{
render(){<div>
... Some content here ...
<div>{this.props.customProp}</div>
</div>}
}
export default MyComponent
and use it in another component like
import MyComponent from './MyComponent';
export class OtherComponent extends React.Component {
render() {
return (
<div>
... Some content here ...
<MyComponent customProp={someDynamicStringValues}/>
</div>
);
}
}
and you can do it recursively

Can I write Component inside Component in React?

I have come across many sources which talk about how to do Component nesting. However, whenever I try to create a Component inside another Component my code fails.
class parent extends React.Component{
class child extends React.Component{
render(){
return <div><h1>Hiiii</h1></div>;
}
}
render(){
return <div><DEF /></div>;
}
}
You can't do that. You can do this on the same file (not same component)
class DEF extends Component {
render() {
return (
<div>
<h1>Hiiii</h1>
</div>
);
}
}
export default class ABC extends Component {
render() {
return (
<div>
<DEF />
</div>
);
}
}
You can't define class inside another class and I don't see why you would want to.
In React you can define Components in two ways: a stateful component (class) or a functional component (function). Stateful components should only be used when you need to manage state locally.
You can do something like:
export default class MyStatefulComponent extends Component() {
render() {
return (
<div><MyFunctionalComponent {...this.props} /></div>
)
}
}
function MyFunctionalComponent(props) {
return <h1>I am functional</h1>
}
I have used the spread operator to pass on the props from the stateful to the functional component, but you should probably pass the individual props as needed..
Comoponent nesting means rendering react components inside other components. Like
<ParentComponent property={value}>
<div>
<ChildComponent />
...
</div>
</ParentComponent>
This is how you can achieve what you are trying to do.
class ABC extends React.Component {
render() {
class DEF extends React.Component {
render() {
return (
<div>
<h1>Hiiii</h1>
</div>
);
}
}
return (
<div>
<DEF />
</div>
);
}
}
Yo can just define component as a static property of other component
class Test extends Component {
static SubTest=props=><div>SubTet</div>
render(){
return(
<div>Test component</div>
)
}
<Test />
<test.SubTest />

react dynamic render with number

my page.js
class R1 extends React.Component {
render() {
return (
<div className="r1">
<h1>level1</h1>
</div>
);
}
}
class R2 extends React.Component {
render() {
return (
<div className="r2">
<h1>level2</h1>
</div>
);
}
}
my main.js
important * as Page from './page';
class App extends React.Component {
render() {
return (
<div className="r1">
<Page.R+level/>
</div>
);
}
}
Skip getInitialState,
I want to dynamic render with level.
I try React.renderComponent(<Page.R+this.state.level />, document.body);
It's not working with failed: SyntaxError
Is there more easily way? or is dynamic render available?
thanks
Not sure how you are exporting your Components so there is an assumption here, generally it is convention to put them in different files.
You can render in your parent component using an if statement inside JSX like this:
class App extends React.Component {
render() {
var renderPage;
if (something) {
renderPage = <PageOne />;
} else {
renderPage = <PageTwo />;
}
return (
<div>
{renderPage}
</div>
);
}
}
main.js can be modified like this to achieve what you want
import * as Page from './page';
class App extends React.Component {
render() {
const level = 2;
return (
<div className="r1">
{/*You use loop over list to get value of level and render all the pages*/}
{React.createElement(Page[`R${level}`], null)}
</div>
);
}
}
Page is an object and we are trying to access the pages and rendering the component name which is in string type.

Resources