Home > other >  React Typescript how to add a counter for each item instantiated?
React Typescript how to add a counter for each item instantiated?

Time:11-27

I see some similar questions have been posted, but I am stuck with my issue considering it's a bit different. My question is that how can I add counting (like 1,2) for each list in the same line?

`


class AttendeeListPage extends Component<any,any> {
        ...
        render(){
        let attendarr: any[] = [];
        let countArr : number[] = [];
        for (let i = 0; i < this.state.arr.length; i  ){
            countArr.push(i 1);
            attendarr.push(<AttendeeBox
                email={this.state.arr[i][0]}
                status={this.state.arr[i][1]}
                eventNum={this.props.eventNum}
            />)
        }

        return (
            <div className='App'>
                <div>
                    {countArr}
                    {attendarr}
                </div>
            </div>
        );
        }
}

export default AttendeeListPage;

`

My AttendeeBox file:

`

class AttendeeBox extends Component<any,any> {
    constructor(props:any){
        super(props);
        this.state = {id: this.props.eventNum(), updateForced: false, ForceUpdateNow: false}
    }
    componentDidMount(): void {
        this.setState({ForceUpdateNow:true})
    }
    componentDidUpdate(prevProps: Readonly<any>, prevState: Readonly<any>, snapshot?: any): void {
        if(this.state.id !== this.props.id){
            this.setState({id: this.props.id});  //should probably be id: this.state.id
        }
    }

    render() {
        return (
            <div className='AttendeeBox'>
                <div className='listElement'>
                    Email : {this.props.email}  &nbsp;
                </div>
                <div className='listElement'>
                    Status : {this.props.status}
                </div>
            </div>
        )
    }
}

export default AttendeeBox;

`

My attempt looks like: enter image description here

As you can see, the counter is seperated from the list box and positioned on top of it. I'm not sure how to make them work together. Thanks!

CodePudding user response:

I agree with @dkunrath that using map would be better.

Also I'd like to add that if your end goal is this

1 Email: [email protected]               STATUS: WILLATTEND
2 Email: [email protected]               STATUS: WILLATTEND

it would be better to add another property to AttendeeBox to render the number with it. This would make it easier.

For example

class AttendeeListPage extends Component<any,any> {
        ...
        render(){
        let attendarr: any[] = [];
        for (let i = 0; i < this.state.arr.length; i  ){
            attendarr.push(<AttendeeBox
                email={this.state.arr[i][0]}
                status={this.state.arr[i][1]}
                eventNum={this.props.eventNum}
                order={i 1}
            />)
        }

        return (
            <div className='App'>
                <div>
                    {attendarr.map(attendee => <div>{attendee}</div>)}
                </div>
            </div>
        );
        }
}

export default AttendeeListPage;
class AttendeeBox extends Component<any,any> {
    constructor(props:any){
        super(props);
        this.state = {id: this.props.eventNum(), updateForced: false, ForceUpdateNow: false}
    }
    componentDidMount(): void {
        this.setState({ForceUpdateNow:true})
    }
    componentDidUpdate(prevProps: Readonly<any>, prevState: Readonly<any>, snapshot?: any): void {
        if(this.state.id !== this.props.id){
            this.setState({id: this.props.id});  //should probably be id: this.state.id
        }
    }

    render() {
        return (
            <div className='AttendeeBox'>
                <div>{this.props.order}</div> 
                <div className='listElement'>
                    Email : {this.props.email}  &nbsp;
                </div>
                <div className='listElement'>
                    Status : {this.props.status}
                </div>
            </div>
        )
    }
}

export default AttendeeBox;

CodePudding user response:

I believe this is a matter of structure/CSS, also, your countArr is just an array of numbers, there is no structure for it, so you'll have to use a .map and some HTML structure to hold it in place.

class AttendeeListPage extends Component<any,any> {
        ...
        render(){
        let attendarr: any[] = [];
        let countArr : number[] = [];
        for (let i = 0; i < this.state.arr.length; i  ){
            countArr.push(i 1);
            attendarr.push(<AttendeeBox
                email={this.state.arr[i][0]}
                status={this.state.arr[i][1]}
                eventNum={this.props.eventNum}
            />)
        }

        return (
            <div className='App'>
                <div className='indexes'>
                    {countArr.map(index => <div>{index}</index>}
                </div>
                <div className='container'>
                    {attendarr}
                </div>
            </div>
        );
        }
}

export default AttendeeListPage;

Component CSS:

.App {
  display: flex;
}

the div indexes return all count in countArr inside other divs, which then hold one above the other. Similarly, you cound use countArr.push(<div>i 1</div>) and adjust the code.

Hope this makes sense, if not I can use code sandbox to better present it.

  • Related