You might consider filtering the members you want to display first, then displaying the length of the resulting array, and mapping over it to render the members:
Fiddle
render() {
const membersToRender = this.state.members.filter(member => member.display)
const numRows = membersToRender.length
return (
<div>
<p>Number of rows = {numRows}</p>
{
membersToRender.map((member, index) => {
return <p key={index}>{ member.name }</p>
})
}
</div>
);
}
Edit: Thanks Edgar Henriquez, I fixed the key properties warning as you suggested
Answer from Michael Horn on Stack OverflowYou might consider filtering the members you want to display first, then displaying the length of the resulting array, and mapping over it to render the members:
Fiddle
render() {
const membersToRender = this.state.members.filter(member => member.display)
const numRows = membersToRender.length
return (
<div>
<p>Number of rows = {numRows}</p>
{
membersToRender.map((member, index) => {
return <p key={index}>{ member.name }</p>
})
}
</div>
);
}
Edit: Thanks Edgar Henriquez, I fixed the key properties warning as you suggested
I think it's a good idea to extract it to the component:
JSFiddle Example
class App extends React.Component {
constructor() {
super()
this.state = {
members: [
..
],
visibleMembers() {
return this.members.filter(m => m.display)
}
}
}
render() {
const members = this.state.visibleMembers()
return (
<div>
<p>Number of rows = {members.length}</p>
{members.map(m => <p key={ m.id }>{ m.name }</p>)}
</div>
)
}
}
I've added key attribute to suppress a warning, you can read more about it on React Documentation.
So I have a child component that takes the length of an array.
Should I create a state variable that keeps track of the array's length, or just pass array.length to the prop?
const [arrLen, setArrLen] = useState(), and then update with useEffect when [array] gets updated?
just pass array.length to the child component?
You can render conditionally.
<div class="results">
{result?.length > 0 ?
<>
<h1>
<b>Scan Results</b>
</h1>
<h3>{results.length} results returned</h3>
<table class="styled-table">
{...}
</table>
</>
:
<h1>No results found</h1>
}
</div>
You can create a new component for the results table
const ResultsTable = ({ results }) => {
if (results?.length === 0) return <h3>No results found</h3>;
if (results?.length === 1) return ...;
return (
<table class="styled-table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{results.map((result) => (
<tr>
<td>{result.id}</td>
<td>{result.name}</td>
</tr>
))}
</tbody>
</table>
)
}
hi i have this empty array which i pushed 6 numbers from 6 loops but when i try to get the array length in render, it gives back 0. Why is this so?
this is my function displayPokemons(ids) {
this.setState({txtStatus: "5"})
var results = [];
for (let id of ids) {
console.log("aa" + id);
this.getPokemonDetails(id).then(function(id) {
results.push(id)
})
this.setState({displayedPokemons2: results})
}}
and then in render
render() {
{console.log(this.state.displayedPokemons2)}
{console.log(this.state.displayedPokemons2.length)}
}
{console.log(this.state.displayedPokemons2)} gives me the 6 elements in the array
but {console.log(this.state.displayedPokemons2.length)} gives me 0.
Soooo, I am developing an app in react, and one of the components is a history of search made by the user, and let's say I want to keep maximum of 5 elements in the array. The array is getting bigger each time the user clicks on an element. I tried to use for loop and map method but it didn't work as i wanted it to. You guys have any idea? cheers.
This is the logic for useState hook.
const historyHandler = (histValue) => {
setHistory((prevHistory) => { return [ ...prevHistory, { name: histValue, id: Math.random().toString(), }, ]; }); };
Here is the JSX in another component:
<Column>
<History history={history}></History> </Column>
And here is the component:
export const History = (props) => {
return ( <Container>
<h3>History:</h3><ul className="history">{props.history.map((point) => (<li key={point.id}>{point.name}</li>))}</ul></Container>);};
Any feedback would be useful :)
You can use Array#fill
const arr = Array(20).fill(1)
console.log(arr)
This will not be fixed as you can't fix an array's length, but you can do according checks in order not to push anything to this array once created. You can create a fixed Object however, using Object.seal
UPDATE:
Apparently, you can use Object.seal() on arrays too:
const object1 = Array(10).fill(0)
Object.seal(object1);
object1[2] = 24;
console.log(object1)
object1.push(8)
console.log(object1)
object1.pop()
console.log(object1)
And if you use Object.freeze() it also doesn't allow any changes in the array. You can still change the values of indices using seal()
Well if you're trying to test something in JSX or just to print there a fixed number of elements, this is great and worked for me. Hopefully, this will help you.
{Array.from({length:3}).map((element,index) => <p>{element} {index} </p>)}
You can use Array#fill
const arr = Array(20).fill(1)
console.log(arr)
This will not be fixed as you can't fix an array's length, but you can do according checks in order not to push anything to this array once created. You can create a fixed Object however, using Object.seal
UPDATE:
Apparently, you can use Object.seal() on arrays too:
const object1 = Array(10).fill(0)
Object.seal(object1);
object1[2] = 24;
console.log(object1)
object1.push(8)
console.log(object1)
object1.pop()
console.log(object1)
And if you use Object.freeze() it also doesn't allow any changes in the array. You can still change the values of indices using seal()
Well if you're trying to test something in JSX or just to print there a fixed number of elements, this is great and worked for me. Hopefully, this will help you.
{Array.from({length:3}).map((element,index) => <p>{element} {index} </p>)}
Because this.state.items starts out as an empty array (which is strange, since later on it looks like its an object) You first need to make sure this.state.items.content is defined
Do it like this:
console.log(this.state.items.content && this.state.items.content.length);
Or in your actual case
if(this.state.items.content && this.state.items.content.length > 0){
//access values from this.state.items
}
Hope this helps
The state is being initialized as an array but you're accessing content (which is undefined):
{
loading: true,
error: false,
items: []
};
To avoid making an further changes, initialize the state so it follows the same structure as the response. For example:
{
loading: true,
error: false,
items: { content: [] }
};
Instead of storing a separate variable for the length of the items array, you can use this.state.items.length directly in the render method.
render() {
return <div>Total Items {this.state.items.length}</div>
}
class App extends React.Component {
state = {
items: []
};
addItem = () => {
this.setState(({ items }) => ({ items: [...items, Math.random()] }));
};
render() {
return (
<div>
<div>Total Items {this.state.items.length}</div>
<button onClick={this.addItem}>Add item</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
var dataa = {
name : "amine",
op : []
}
class App2 extends React.Component {
constructor(props) {
super(props);
this.state = {
myarray : dataa.op
}
}
increment = (e) => {
e.preventDefault();
const option = e.target.elements.namee.value;
console.log(option)
this.state.myarray.push(option)
this.setState({myarray : this.state.myarray })
console.log(this.state.myarray)
}
render() {
return(
<div>
<p>{this.state.myarray.length}</p>
<form onSubmit= {this.increment}>
<input type="text" name ="namee" />
<button type="submit">add option</button>
</form>
</div>
);
}
}
export default App2;