4

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?

2 Answers 2

10
  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.

Sign up to request clarification or add additional context in comments.

1 Comment

This helped a lot. Thank you.
0

You cannot return a new statement from inside an async function such as map() which is already inside your main function. You must pass a callback in the parent function. Try something like this:

function foo(callback){
  const bigObject = [{
        textArray: [*array of length 4 to 8*],
        imgSrc: "string goes here"
   }, {
        textArray: [*array of length 4 to 8*],
        imgSrc: "string goes here"
   }];
   if(bigObject.length>0){
      bigObject.map((obj)=>{
        callback(obj);
      });
   }
}

Now you can call all the value from bigObject inside your render method like so:

render(){
  return (
    <div>
      {this.foo(e){ console.log(e.textArray); }}
    </div>
  )
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.