Display content from an array in React

Hi guys,

I’ve been stuck on this for a couple of hours now.

Here is my Component:

import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';

class AboutMe extends React.Component {
    render () {
        const arr = ["a", "b", "c"];
        return (
            <Row>
                <Col className="about-wrapper">
                    <div className="about-name">
                        <span>{arr.map((item , index) => item[index])}</span>
                    </div>
                </Col>
            </Row>
        );
    };
}

What I’m trying to do is the following:

  • Display element from arr one by one
  • Replace the value within the span (not create multiple span)

So, with each iteration it replaces the span content with the value of item[index].

Can you explain me what I’m doing wrong please?

Can you clarify what’s <Row> </Row> etc.? I believe the code won’t compile using custom elements like that. So first off I would re write it like this:


class AboutMe extends React.Component {
    render () {
        const arr = ["a", "b", "c"];
        return (
                    <div className="about-name">
                        <span>{arr.map((item , index) => item[index])}</span>
                    </div>
        
        );
    };
}

At the same time, it makes it easier to debug.

For just ‘pasting in’ the elements I’d change the expression between curly braces by this

     arr.join(' ')

But if you really want to use map then maybe try this:

{arr.map((item , index) => item)}
By the way, thanks for making a good question :slight_smile:
Hope this will guide you in the right direction.


Off topic: when playing with react I usually use this website called jscomplete.

First of all, this:

arr.map((item , index) => item[index])

isn’t doing what you think. You want:

arr.map(item => item)

But I’m not sure how that will work. You may need an element in there, even a Fragment. Maybe you want:

arr.join();

or something like that.

Thank you for the quick answers.

Regarding <Row> </Row> this is simply a Bootstrapped element from react-bootstrap I’ve edited my code, so you can see the imports, sorry about the confusion.

I’ve tried arr.map(item => item) which solve only the single span problem, but it’s still displays like this abc.

What I would like to do is:

  • Display a then a fades out
  • Display b then b fades out (at this point b just took the place of a within the span)
  • ect…

I work with animations (I feel like I should have say that earlier… Sorry about this) this a micro feature that I’d like to implement for my portfolio.

Yeah, that’s a little beyond my ken. This is probably going to be an animation thing which I haven’t worked much with that part of React. It sounds like you either want them replacing each other of have those elements overlap and have them fade in and out on cue.

1 Like

I see…
I’ve done a couple of searches and nothing seems to be very easy. But I wonder why not to do it just using plain js. For that, you only need a setInterval or setTimeout function, that updates the innerHTML of a span (where you can add an id).

Maybe that’s not what you’re looking for, but just in case.

I thought it was something easy, that I wasn’t figuring out, but yeah, it seems more difficult than expected.

However, thanks a lot for taking the time to do recherches.
I’m not using plain JS or jQuery because I want to learn to work with the React library.

Yeah, you can use a setInterval to get them to change - that’s easy. To get the fade in and fade out - that’s a little more complicated. Maybe something with transform would work.

I am going to give it a try.

Take a look here:

Not at all sure of what I’m doing, but I guess it’s not that far from your requirements (working version here):

 class AboutMe extends React.Component {
  constructor(props){
  super(props)    
  this.arr = ["a", "b", "c"]
  this.state = {value: "initial value", init:-1}    
  this.tick = this.tick.bind(this);
  }  

  //this is executed after the first value is set.
    componentDidMount() {
      this.timerID = setInterval(
      () => this.tick(), 2000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }


  tick() { 
    if (this.state.init<this.arr.length-1){
      this.setState({value:this.arr[this.state.init + 1], init:this.state.init+1}); }
    else {this.setState({value:"initial value", init:-1})}
  }
  render () {
        
        return (
                    <div className="about-name">
                        <span>{this.state.value}</span>
                    </div>
        );
    };
}
ReactDOM.render(<AboutMe/>, document.getElementById("root"))

Now you should update the state and setState to update the classList, or something like that. Idk how difficult it may be.

Thank you for taking the time to work on a solution.

I’ve decided to move on to a backup feature in order to be able to continue my work on my portfolio.
However, I am implementing improvement quite regularly, and I will definitely try out your solution, so once again, thanks a lot for your time.

On a side note, I thought all the ‘will’ Lifecycle methods were out of date?

You’re welcome, it was a nice question. We can build something in react together whenever you want :slight_smile:

1 Like

Nope, componentWillUnmount is still going strong.

1 Like

Something like:

@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
    
    
.oneOfMyMappedItems {
  animation-name: fadein;
  animation-duration: 1s;
  animation-fill-mode: forwards;
  opacity: 0;
}
<>
  { itemsIWantToMap.map((item, index) => (
    <Item
      key={someUniqueID}
      style={{animationDelay: `${index}s` }}
    />
  )}
</>

Example:


You would probably want to have the height of each at 0 to start with, to avoid them taking up space. You can do what you want really, within reason.

Note that more complex sequenced animations are easier in JS. React complicates things because of how it works (animation involves tracking a value over time, React normally just blows the value away and rerenders immediately with a new value). There are several pretty good libraries – React Transition Group/CSS Group used to be part of React years ago, it’s maintained now as a seperate library. React Spring is really good but docs are imo a bit light. Pose and Framer Motion seem to be pretty good as well.

1 Like

This is not quite what I tried to do.
The logic that I was trying to implement was something like this:

  • Display first item
  • Hide first item
  • Display second item
  • Hide second item
  • ect…

For as many items I would have had in my array, like a “Strobe Light effect” except that instead of the colors it would have been words/sentences.

Remove animation-fill-mode: forwards and the animation will snap back to its initial state

Yep, I’ve been using animations via CSS for the very first version of my portfolio. then I used a lib called AOS to handle animations.
I think I know how I would implement this now.

But I’ve reworked my portfolio entirely, because I wanted something original, but the kind of original I wanted would actually require a much much much better understanding of React.

If you want to really understand what I had in mind at first.

You can check my Portfolio
(It’s still a WIP, as I said, I’m improving it regularly, and I will change the text later, I’m awful when it comes to market myself… haha)

Anyway, back to the main subject, instead of the “Typing” part I would have put the “Strobe Light effect”.

At this point, I am not really sure if this kind of effect would have a place in my Portfolio.