Skip to main content
update answer based on follow up ques
Source Link
Andrew
  • 319
  • 1
  • 3

Note that React.memo isn't the silver bullet to all render problems and you have to split up components intelligently. React.memo does a shallow check, which means it's very good with primitives, like strings, booleans and numbers. Notice that the parts I pulled out into its own separate component only has a boolean as a prop. That was very intentional. React.memo can easily do a comparison and stop a rerender.

Edit: Apologies, I didn't notice that this.handleScroll is already an arrow function. You don't need to bind in that case. Here, all I did was remove the bind inside the click handler.

handleScroll = (e) => {
  const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
  if (bottom) {  
      this.setState({
          storiesLoaded: this.state.storiesLoaded + 25
      });
  }
}

renderResults(Object, isVisible, commodityStates, languageStates, publishedStates) {
  if (isVisible){
      return (
          <div className="search-result-master-container">
              <span className="section-header">{Resources.Filter_By}</span>
              <span className="section-header">{Object.length} {Resources.Results}:</span>
              <div id="filterBySideBar">
                  <div className="horizontal-line-filter">
                      <div>{this.renderCategories(Object , commodityStates)}</div>
                      <div>{this.renderLanguage(Object , languageStates)}</div>
                      <div>{this.renderPublished(publishedStates)}</div>
                  </div>
              </div>
              <div className="horizontal-line-stories-top"/>
              <div className="scrollbar"  onScroll={this.handleScroll}>
                  <div className="force-overflow">
                          {this.renderStories(Object)}
                  </div>
              </div>
              <div className="horizontal-line-stories-bottom" />
          </div>    
      );       
  }                 
}

But for a function with a callback, you can write it out to have the functions be double returns:

addNewBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/newstestAddNewBookmark?userId=' + (userId), 
  { 
      UserID: userId,
  })
  .done(() => {
    this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}

removeBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/test/RemoveBookmark?userId=' + (userId), {})
  .done(() => {
      this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}

renderBookmarkButton(userId, newsId, isBookmarked, bookmarkIndex) {  
  return (
      <a onClick={isBookmarked == false ? this.addNewBookmark(userId, newsId, isBookmarked, bookmarkIndex) : this.removeBookmark(userId, newsId, isBookmarked, bookmarkIndex)}>
          <img className={isBookmarked == false ? "bookmark-button" : "bookmark-button bookmark-button-fill-color"} src="/images/logo/Bookmark.svg" />
      </a>
  );
}

Notice how I don't have () => inside the onClick

Note that React.memo isn't the silver bullet to all render problems and you have to split up components intelligently. React.memo does a shallow check, which means it's very good with primitives, like strings, booleans and numbers. Notice that the parts I pulled out into its own separate component only has a boolean as a prop. That was very intentional. React.memo can easily do a comparison and stop a rerender

Note that React.memo isn't the silver bullet to all render problems and you have to split up components intelligently. React.memo does a shallow check, which means it's very good with primitives, like strings, booleans and numbers. Notice that the parts I pulled out into its own separate component only has a boolean as a prop. That was very intentional. React.memo can easily do a comparison and stop a rerender.

Edit: Apologies, I didn't notice that this.handleScroll is already an arrow function. You don't need to bind in that case. Here, all I did was remove the bind inside the click handler.

handleScroll = (e) => {
  const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
  if (bottom) {  
      this.setState({
          storiesLoaded: this.state.storiesLoaded + 25
      });
  }
}

renderResults(Object, isVisible, commodityStates, languageStates, publishedStates) {
  if (isVisible){
      return (
          <div className="search-result-master-container">
              <span className="section-header">{Resources.Filter_By}</span>
              <span className="section-header">{Object.length} {Resources.Results}:</span>
              <div id="filterBySideBar">
                  <div className="horizontal-line-filter">
                      <div>{this.renderCategories(Object , commodityStates)}</div>
                      <div>{this.renderLanguage(Object , languageStates)}</div>
                      <div>{this.renderPublished(publishedStates)}</div>
                  </div>
              </div>
              <div className="horizontal-line-stories-top"/>
              <div className="scrollbar"  onScroll={this.handleScroll}>
                  <div className="force-overflow">
                          {this.renderStories(Object)}
                  </div>
              </div>
              <div className="horizontal-line-stories-bottom" />
          </div>    
      );       
  }                 
}

But for a function with a callback, you can write it out to have the functions be double returns:

addNewBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/newstestAddNewBookmark?userId=' + (userId), 
  { 
      UserID: userId,
  })
  .done(() => {
    this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}

removeBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/test/RemoveBookmark?userId=' + (userId), {})
  .done(() => {
      this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}

renderBookmarkButton(userId, newsId, isBookmarked, bookmarkIndex) {  
  return (
      <a onClick={isBookmarked == false ? this.addNewBookmark(userId, newsId, isBookmarked, bookmarkIndex) : this.removeBookmark(userId, newsId, isBookmarked, bookmarkIndex)}>
          <img className={isBookmarked == false ? "bookmark-button" : "bookmark-button bookmark-button-fill-color"} src="/images/logo/Bookmark.svg" />
      </a>
  );
}

Notice how I don't have () => inside the onClick

update answer based on follow up ques
Source Link
Andrew
  • 319
  • 1
  • 3

Edit: Apologies, handleScroll was a bad example because the method is already an arrow function. In that situation, you can just take off bind and it will work the same way. But your addNewBookmark is far trickier. Turn it into a double return arrow function. You circumvent the need to bind and use an anonymous function inside the click handler

addNewBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/newstestAddNewBookmark?userId=' + (userId), 
  { 
      UserID: userId,
  })
  .done(() => {
    this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}

Edit: Apologies, handleScroll was a bad example because the method is already an arrow function. In that situation, you can just take off bind and it will work the same way. But your addNewBookmark is far trickier. Turn it into a double return arrow function. You circumvent the need to bind and use an anonymous function inside the click handler

addNewBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/newstestAddNewBookmark?userId=' + (userId), 
  { 
      UserID: userId,
  })
  .done(() => {
    this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}
update answer based on follow up ques
Source Link
Andrew
  • 319
  • 1
  • 3

Edit: Apologies, handleScroll was a bad example because the method is already an arrow function. In that situation, you can just take off bind and it will work the same way. But your addNewBookmark is far trickier. Turn it into a double return arrow function. You circumvent the need to bind and use an anonymous function inside the click handler

addNewBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/newstestAddNewBookmark?userId=' + (userId), 
  { 
      UserID: userId,
  })
  .done(() => {
    this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}

Edit: Apologies, handleScroll was a bad example because the method is already an arrow function. In that situation, you can just take off bind and it will work the same way. But your addNewBookmark is far trickier. Turn it into a double return arrow function. You circumvent the need to bind and use an anonymous function inside the click handler

addNewBookmark = (userId, newsId, isBookmarked, bookmarkIndex) => () => {
  $.post('/webapi/newstestAddNewBookmark?userId=' + (userId), 
  { 
      UserID: userId,
  })
  .done(() => {
    this.changeBookmarkState(isBookmarked, bookmarkIndex);
  }
}
added 3 characters in body
Source Link
Andrew
  • 319
  • 1
  • 3
Loading
Source Link
Andrew
  • 319
  • 1
  • 3
Loading