Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Calling a function inside a map function

Here's the basic layout of the object I'm using (being passed as a prop to the component):

bigObject {
    overview: {
        *not being used for current concern*
    },
    code: {
        1: {
            textArray: [*array of length 4 to 8*],
            imgSrc: "string goes here"
        },
        2: {
            textArray: [*array of length 4 to 8*],
            imgSrc: "string goes here"
        },
        3: {
            textArray: [*array of length 4 to 8*],
            imgSrc: "string goes here"
        },
    }
}

My constructor:

constructor(props) {
    super(props);
    this.state = {
        projectName: this.props.projectName,
        info: bigObject[this.props.projectName]
    }
    this.renderInfo = this.renderInfo.bind(this);
    this.renderText = this.renderText.bind(this);

    console.log(this.state.info);
}

What I'm trying to do is iterate through the code object so that for each imgSrc, the text array in the object with it is iterated over to create list elements along side the photo.

renderInfo() {
    return Object.keys(this.state.info.code).map(function(key, index) {
        return (
            <div className="code-snippet" id={name + key} key={key}>
                <div className="code-description">
                    <ul>
                        {() => this.renderText(key)}
                    </ul>
                </div>
                <div className="code-img">
                    <img src={"/project-images/MongoScraper/" + placeholder[key].img} alt=""/>
                </div>
            </div>
        )
    });
}

Each img is rendered exactly how I want, but the renderText method isn't iterating through the textArray like I want:

renderText(key) {
    console.log("hello world") //doesn't log
    let placeholder = this.state.info.code;
    return placeholder[key].text.map(function(keyValue, index) {
        return (
            <li>{placeholder[key].text[index]}</li>
        )
    });
}

The render() method:

render() {
    return (
        <div className="container code-descriptor-div">
            {this.renderInfo()}
        </div>
    )
}

I'm using an arrow function when I call the renderText method because of lexical scoping concerns ("cannot read property of undefined" results from not using the arrow function), but I know the method isn't being called at all because the console isn't logging "Hello world".

When I call the renderText method inside of the render() method, it will render the list elements properly, but doing that doesn't work with how I'm structuring other components.

Is there a way to iterate through the textArray like I want?

like image 767
Daniel Ertel-Moore Avatar asked Dec 23 '22 13:12

Daniel Ertel-Moore


1 Answers

  1. You're not actually calling your function. you're passing a new function.

Change

{() => this.renderText(key)}

to:

{this.renderText(key)}
  1. You're fixing the lexical scoping in the wrong spot. You're still using function for map.

change:

.map(function(key, index) {

to:

.map((key, index) => {

When writing React code, use arrow functions everywhere. It will be a very rare case where you need to use the function keyword.

like image 144
azium Avatar answered Dec 31 '22 02:12

azium