How to Iterate and Get React State Object Values? - reactjs

Here is my simple react component.
export default function App() {
const [stats, setStats] = React.useState(() => {
return {
name: "",
lvl: 1
}})
let displayStats;
for(let key in stats) {
displayStats += <p>{key}</p>
}
return (
<>
{displayStats}
</>
)
}
This displayStats variable returns 'undefined[object Object][object Object]' on the screen. Why? What am I doing wrong.

Change your code to this
return (
<>
{Object.keys(stats).map(key => <p>{key}</p>)}
</>
)
-> If you want to iterate through only values use Object.values(objName)
-> If you want to iterate through both values and keys use Object.entries(objName)

Try using the key on the stats object.
Change
displayStats += <p>{key}</p>
To
displayStats += <p>{stats[key]}</p>

Related

React component error message using filter method

Why am I getting a Type Error: Cannot read properties of undefined (reading 'filter') with the following React component? (I can console.log "squads" and "weekNo" and get the correct results)
import React from "react";
const Weekly = ({ squads, weekNo }) => {
return (
<>
<div>
{squads
.filter((squad) => squad.division === "NFC North")
.map((filteredDivision) => (
<li>{filteredDivision}</li>
))}
</div>
<div>
<p>{weekNo}</p>
</div>
</>
);
};
export default Weekly;
I'll add some comments to your code.
{squads
// 1
.filter((squad) => squad.division === "NFC North")
// 2
.map((filteredDivision) => (
<li>{filteredDivision}</li>
))}
Assuming squads is an array like below,
[{ division: 'a' }, { division: 'b' }]
After your statement 1, it gets all element with division set to "NFC North".
Now at your statement 2, remember it's still an array of objects. You can't print out an object directly. But you can print out one property of an object.
.map((squad) => (
<li>{squad.division}</li>
))
Hope this makes sense now.
NOTE: filter or map produces a new array.
Make sure the squads is valid at the first place. For example.
const Weekly = ({ squads, weekNo }) => {
if (!squads) return null
return (...)

why I get 'not a function' error in mapping array

I have o idea why I am getting TypeError: sheltersList.map is not a function when it should map the array instead? What is wrong with my code? I dont understand it..
import React from 'react';
const SheltersList = (sheltersList) => {
console.log(sheltersList);
if (sheltersList.lenght != 0) {
return (
<div>
{ sheltersList.map(function(shelter) {
<option id={shelter.id}>{shelter.name}</option>
})}
</div>
)
} else { return (
<option> loading... </option>
)}
}
export default SheltersList;
map is a function of the Array.prototype. It seems like the parameter sheltersList is not an Array.
Sine this is a React functional component, you might find your sheltersList Array from sheltersList.sheltersList in this case.
When you passing props to components by their name you should use destructuring syntax.
const SheltersList = ({ sheltersList }) => { // sheltersList is your list
Now your list is inside prop called "sheltersList". When you passed it like before your list is rather inside object named "sheltersList" which in this case should be rather named "props"
const SheltersList = ( sheltersList ) => { // sheltersList contains all props and your list is probably inside sheltersList.sheltersList
When you use destructuring you can also set default value to be sure if everything works fine when you forgot to pass sheltersList.
const SheltersList = ({ sheltersList = []}) => {

how to render array in object in array? (react)

const checked = [{
food:['apple', 'banana']
drink:['wine', 'beer']
}];
render (
<>
{checked.map((value) => {
value.food.forEach((each) => (
<div>{each}</div>
)
)}
</>
)
I tried this way and noting is shown in browser..
what would be the best way to approach?
Need to Return Your data like below!!
import React from "react";
export default function App() {
let checked = [{
food:['apple', 'banana'],
drink:['wine', 'beer']
}];
return (
<div className="App">
{
checked.map((item) => {
return item.food.map((fruit)=>{
return <h1>{fruit}</h1>
})
})
}
</div>
);
}
Your code has multiple errors.
It should be render instead of rander
While defining object, multiple properties should be separated using a comma. So put comma after the food array.
forEach doesn't return any thing. It just iterates over an array. So, if you want to return something (in this case a div element), use map.
Also, you should use key for each div element otherwise react would give you a warning in the console. This is done so that while re-rendering, based on the keys, react would understand which component to re-render and which to skip. Otherwise all the div would be re-rendered which is a costly operation.
const checked = [
{
food: ["apple", "banana"],
drink: ["wine", "beer"]
}
]
return (
<>
{checked.map((value) => {
return value.food.map((each, index) => {
return <div key={index}>{each}</div>;
});
})}
</>
);
There is a couple of improvements that require to be implemented to make the list displayed.
First, the map method does not return anything.
Two solutions:
Remove the curly brackets checked.map((value) => value...
Add a return keyword: checked.map((value) => { return value...}
The other issue is that the second loop is iterated using the forEach method.
The difference between the two (forEach and map) from MDN:
The forEach() method executes a provided function once for each array
element.
MDN
The map() method creates a new array populated with the results of
calling a provided function on every element in the calling array.
MDN
Basically, it means that forEach does not return anything and that why you need to use map
checked.map((value) => {
return value.food.map((each) => (<div>{each}</div>))
})}
or
checked.map((value) =>
value.food.map((each) => (<div>{each}</div>))
)}
You are iterating over the checked array items using forEach which won't induce any results since the forEach method
executes a provided function once for each array element.
which won't result in a transformed array.
What you are looking for is the map method which
creates a new array populated with the results of calling a provided function on every element in the calling array.
hence returning your transformed items so that they can be rendered (transformed at compilation time to ReactElement using the JSX syntax).
Note that you need to use an HTML tag instead of a React.Fragment the empty tag <> syntax:
const checked = [{
food:['apple', 'banana'], // there is a missing comma here
drink:['wine', 'beer']
}];
render ( // render and not rander
<div> // div instead of empty tag
{checked.map((item) => item.food.map((each) => <div>{each}</div>))}
</div>
)
Can check this approach. if you want to print just food values, below code should work. If you want to print all the values (both food and drink), then uncomment the commented code below.
export default function App() {
const checked = [
{
food: ["apple", "banana"],
drink: ["wine", "beer"]
},
{
food: ["grapes", "oranges"],
drink: ["coke", "sprite"]
}
];
// to display values of all arrays.
// return (
// <>
// {checked.map((value) => {
// const keys = Object.keys(value);
// return keys.map((eachKey) => {
// return value[eachKey].map((individualValue) =>
// (
// <div>{individualValue}</div>
// )
// )
// });
// })
// }
// </>
// );
// To display just food values.
return (
<>
{checked.map((value) => {
return value.food.map((each) => <div>{each}</div>);
})}
</>
);
}

repeated data array .map () react

can someone tell me why my .map () array is returning the same data several times on thescreen? I would like to show it only once but I don't know why it is repeating,
Can someone help me?
React code below:
console.log('>>> [HistoricosAtendimento] props: ', props);
const viewData = props.historicos || [];
const convertToArray = Object.values(viewData);
return (
<>
<SC.Container>
<SC.Item>
{convertToArray.map((item) => {
console.log('convertToArray', convertToArray);
return (
<SC.Item key={item.protocolo}>
<SC.Description>{item.textNotas}</SC.Description>
</SC.Item>
);
})}
</SC.Item>
Just remove the outer wrapping component:
<SC.Container>
// <SC.Item> <= remove
{convertToArray.map((item) => {
// console.log('convertToArray', convertToArray); // should move out of JSX
return (
<SC.Item key={item.protocolo}>
<SC.Description>{item.textNotas}</SC.Description>
</SC.Item>
);
})}
// </SC.Item> <= remove

can not set data from back end use React.js

This is from back-end data format:
{data: Array(15)}
data[0]:
option: Array(1)
0: "String"
_id: "String"
col1: "String"
col2: "String"
col3: "String"
....data[14]
and this is front end code:
const Component1 = () => {
const [dbvalue, setDbvalue] = useState(null)
//option, _id, col1, col2, col3
const getAlldbValue = async () => {
try {
const resp = await services.getAlldbValue();
console.log(resp) //enter F12 can get total data from back end.
setDbvalue(resp.data.data)
console.log(dbvalue) //setDbvalue() not work , this print null
} catch (error) {
console.log(error)
alert('Failed!')
}
}
useEffect(() => {
getAlldbValue()
}, [])
if(!dbvalue) {
return (
<p>Loading Component...</p> //not appear
)
}
return (
<p>{dbvalue}</p> //not appear
);
};
export default Component1;
How can I set this nested object json into this dbvalue?
I want use dbvalue.keyname to display.
Thanks for your help
To display JavaScript objects in your jsx you can do the following:
<pre>{JSON.stringify(dbvalue,undefined,2)}</pre>
If your data[x].option is an object where every property is a string then you can do the following to list them:
const ListProps = props => (
<ul>
{Object.entries(props).map(([key, value]) => (
<li key={key}>{value}</li>
))}
</ul>
)
//here is how you would render listProps
<listProps {...data[0].option} />
First, your console.log is printing null because when you use setState, the variable you just setted will only be setted in the next render. Try printing resp.data.data instead and then put console.log(dbvalue) outside the getAlldbValue function, so you can understand better.
Also,
`return (
<p>{dbvalue}</p> //not appear
);`
your trying to put an object into a HTML Element, try dbvalue[0].col1 or whatever you want to show instead.
Hope it helps you.

Resources