How can load data of lists using component in ReactJS? - javascript

I am trying to render some data using 'ListItem' component in ReactJS. But the component is not getting the data. I also tried to load the data without using 'ListItem' component. In that case it is successfully rendering.
So, How can i load the data using 'ListItem' component?
import React, { Component } from 'react';
function ListItem(props) {
console.log(props);
return <li>{props.value}</li>;
}
class NumberList extends Component {
constructor(props) {
super(props);
}
render() {
const numbers = this.props.numbers;
const listItems = numbers.map( (number) => {
<ListItem key={number.toString()} value={number} />
});
console.log(listItems);
return(
<ul>
{
// numbers.map( n => {
// return <li>{n}</li>
// } )
listItems
}
</ul>
);
}
}
export default NumberList;

You are returning undefined in your map-function.
Try changing to this:
const listItems = numbers.map( (number) => {
return <ListItem key={number.toString()} value={number} />
});
or:
// By omitting the {} around the callback function body
// you can utilise the implicit-returning feature of arrow functions.
const listItems = numbers.map( (number) => (
<ListItem key={number.toString()} value={number} />
));
// The above example is the same as:
const listItems = numbers.map( (number) => <ListItem key={number.toString()} value={number} />);

You are using the arrow function notation inside the map. When you use it with braces ({ and }), you should add a return to the statement you wish to return.
const add = (a, b) => {
return a + b;
};
When your function has just one statement, you can omit the braces and place only the statement at the right side of the arrow, like this:
const add = (a, b) => a + b;
But if you add the braces, but does not write a return statement, then the function will return undefined. So, this would return undefined:
const add = (a, b) => {
const sum = a + b;
};

You have to return your listitem component from map. You are returning li items in your commented code. But looks like you missed adding return when converting it to use ListItem.

Related

Tyepscript Array.map returns array of JSX.Element instead of custom component type

var items = values.map((x, index) =>
<CustomComponent key={index} />);
This returns JSX.Element[]. Why doesn't it return typeof CustomComponent[]?
With the former, then I can't use items.sort without difficult errors.
It's correct. It returns JSX.Element[] because you are rendering CustomComponent immediately.
If you want to work with element sort/filter or something else you need filter data before render.
values
.filter(x => //filter your values)
.map((x, index) => // render your components
<CustomComponent key={index} />);
yes,
like Egor said, your map result is CustomComponent resuls array.
if you want to your component instance array try some thing like this
export type CustomComponentType = () => JSX.Element;
export const CustomComponent : CustomComponentType = ()=> {
return <div>my componen result</div>
}
export const test : CustomComponentType[] = ()=> {
const array = [1,2,3,4,5,6,7,8,9];
const componentArray = array.map(c => CustomComponent);
return componentArray;
}

Cannot Access props inside function of functional component

I am trying to use props inside function of functional props.
const Inputs = (props) => {
console.log(props.printFirstArray);
const FirstInputSet = () => {
console.log(props.printFirstArray)
}
}
First console.log is logging the value of printFirstArray, but second console.log inside FirstInputSet() function is not logging anything.
Edit: Minimal Code
const Inputs = (props) => {
const FirstInputSet = () => {
return (
<>
<div className="first input-set">
{props.printFirstArray}
</div>
</>
);
}
const renderFirstInputSet = () => {
if (props.firstInputValue)
return <FirstInputSet />
else
return null;
}
return (
<>
{renderFirstInputSet()}
</>
);
}
Neither props.printFirstArray nor props.printSecondArray is not returning anything
From your code, FirstInputSet is a new component and you aren't passing any props.
return <FirstInputSet />
Try to pass your props to the child component but I recommend keeping the child component out of parent component.
OR
If you meant to use FirstInputSet as a function, you can modify the code like below
return FirstInputSet();

How to pass string parameter to nested function, which has already parameters?

This is how my Categories react functional component looks like. For easier testing, I split up the handleClick and the react component itself - but that shouldn't be an issue for this question.
How do I pass the component string value from the map() to the handleClick()? handleClick already passes some operator parameter, which gets me struggling with this simple issue...
export const useCategories = () => {
const handleClick = (operator) => {
updateCategory({
variables: {
id: '123',
operator,
category // <-- this value is missing
}
})
}
return {
icon: {
onClick: handleClick('$pull') // <-- Here I add some operator value
}
}
}
export const Categories = () => {
const { icon } = useCategories()
return (
<div>
{categories.map((category) => <Icon onClick={icon.onClick} />)} {/* <-- how to pass category value to handleClick...? */}
</div>
)
}
In order to "add" a variable, you can use currying.
Hence, return a function that receives the new argument and use it internally:
export const useCategories = () => {
return (category) => {
const handleClick = (operator) => {
updateCategory({
variables: {
id: '123',
operator,
category // now this is the argument of the wrapper function
}
})
};
return () => handleClick('$pull');
};
}
And you can use it like this:
export const Categories = () => {
const getOnClick = useCategories();
return (
<div>
{categories.map((category) => {
const onClick = getOnClick(category);
return <Icon onClick={onClick} />;
})}
</div>
)
}

React hooks - how to access ...other spread and also a named property

In an older class I have the following;
class ComponentItem extends React.PureComponent {
render() {
const { item, ...other } = this.props;
return (
<>...</>
)
}
};
Now I want to refactor and use hooks, but how can I access the named properties, and the "other properties inside a hook?
I tried
const ComponentItem = (props) => {
const classes = useStyles();
const { item, ...other } = props;
return (
<>...</>
)
}
const ComponentItem = (item, ...other) => {
const classes = useStyles();
console.log(item); // takes all passed in props
console.log(...other);
return (
<>...</>
)
}
What is the best way to do this in a function using hooks?
Probably using the rest parameters, like the following:
const ComponentItem = ({item, ...others}) => {
return <>
{ /* return of component */ }
</>
}
Read further here: Rest parameters
I hope this helps!
Wrap the component with React.memo() (the equivalent of PureComponent), and destructure the components props in params:
const ComponentItem = React.memo(({ item, ...other }) => {
const classes = useStyles();
return (
<>...</>
)
})

React component name from factory

I have two components:
const CustomSelfDefinedComponent = () => <React.Fragment />;
const CustomSelfDefinedViaFactoryComponent = (() => () => <React.Fragment />)();
on shallow rendering I get next:
<CustomSelfDefinedComponent />
<Component />
Can anyone point me why in second case I don't have CustomSelfDefinedViaFactoryComponent as a component name in a snapshot?
I see the reason at the fact that it compiles as : [BABEL PLAYGROUND]
"use strict";
var CustomSelfDefinedComponent = function CustomSelfDefinedComponent() {
return /*#__PURE__*/React.createElement(React.Fragment, null);
};
var CustomSelfDefinedViaFactoryComponent = function () {
return function () {
return /*#__PURE__*/React.createElement(React.Fragment, null);
};
}();
Any solutions?
I suppose React relies on function.name to get default component name, so in first case
const CustomSelfDefinedComponent = () => <React.Fragment />;
CustomSelfDefinedComponent.name -> "CustomSelfDefinedComponent"
while in second anonymous function returned and name = ""
To solve that factory function can have explicit displayName argument:
const factory = (..., displayName) => {
const NewComponent = () => { ... }
NewComponent.displayName = displayName
return NewComponent
}
not sure if there's a babel plugin that can simplify it

Categories

Resources