0

I currently have a react project I'm working on. My render method looks like this going into my return method:

   render() {
     let elements = [];
     this.dropdownCounter().forEach(item => {
       if(item != "attributeProduct") {
         console.log('setting');
         elements.push(
           <Dropdown
             title={this.state[item][0]['title']}
             arrayId={item}
             list={this.state[item]}
             resetThenSet={this.resetThenSet}
           />
         );
       }
    });
    this.state.attributeProduct.map(attributeItem => {
      elements.push(
        <Dropdown
          title={attributeItem.name}
          arrayId='attributeMetaProduct'
          list={
            this.state.attributeMetaProduct.filter(metaItem => metaItem.attribute_id == attributeItem.ID)
          }
          resetThenSet={this.resetThenSet}
        />
      );
    });
    return (

I have a lot of code going on in the render area due to different drop downs dependent on other methods. Is there a way that I can do something like this instead?

render() {
  allMyPrereturnStuff()
  return()
}

Then just place all this code in allMyPrereturnStuff()? I've tried creating this function and passing everything there but it doesn't work due to all the "this". Any ideas?

2 Answers 2

3

Yes, you can easily drop in normal javascript expressions into JSX:

return (
  <div>
    {this.renderStuff()}
    {this.renderOtherStuff()}
    {this.renderMoreStuff()}
  </div>
);

You can even base it on flags:

const shouldRenderMoreStuff = this.shouldRenderMoreStuff();

return (
  <div>
    {this.renderStuff()}
    {this.renderOtherStuff()}
    {shouldRenderMoreStuff ? this.renderMoreStuff() : null}
  </div>
);

Do note that it is often an anti-pattern to have render* methods in your components other than the normal render method. Instead, each render* method should probably be its own component.

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

Comments

1

Don't forget to bind your allMyPrereturnStuff() method in the constructor so "this" will work inside it.

constructor(props) {
    super(props);
    // ... your existing code
    this.allMyPrereturnStuff = this.allMyPrereturnStuff.bind(this);
}

allMyPrereturnStuff = (params) => {
   // ... all the code
}

However, you might want to consider breaking out the code to components, which is more Reacty way to do things.

For example, you could refactor this

this.state.attributeProduct.map(attributeItem => {
      elements.push(<Dropdown
        title={attributeItem.name}
        arrayId='attributeMetaProduct'
        list={
          this.state.attributeMetaProduct.filter(metaItem => metaItem.attribute_id == attributeItem.ID)
        }
        resetThenSet={this.resetThenSet}
        />);
    });

To something like (somewhat pseudocody):

const DropdownList = (props) => {
    return (<Dropdown
            title={props.attributeItem.name}
            arrayId='attributeMetaProduct'
            list={props.list}
            resetThenSet={props.resetThenSet}
            />);
}

And in the original component's render function, have something like

render() {
    return (this.state.attributeProduct.map(attributeItem => {
      <DropdownList attributeItem={attributeItem}
        list={ this.state.attributeMetaProduct.filter(metaItem => metaItem.attribute_id == attributeItem.ID) }
        resetThenSet={this.resetThenSet}
        />);
}

1 Comment

Note: you only need to bind the function if the function will be used as a callback.

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.