infinitescroll | old infinitescroll
kandi X-RAY | infinitescroll Summary
Support
Quality
Security
License
Reuse
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample Here
infinitescroll Key Features
infinitescroll Examples and Code Snippets
Trending Discussions on infinitescroll
Trending Discussions on infinitescroll
QUESTION
I'm using react - redux environment for my web app and I'm not able to make an inifinite scroll, Once i reach the bottom, I'm getting an error that useEffect cannot be used. Here is the code below:
import React, { useEffect } from 'react';
import './Homefeed.css';
import StickyNav from '../StickyNav/StickyNav';
import { fetchHomePosts } from '../Redux/HomeFeed-Redux/HomeFeedActionMethods';
import { connect } from 'react-redux';
import PostCell from '../PostCell/PostCell';
import InfiniteScroll from 'react-infinite-scroll-component';
import { useDispatch } from 'react-redux'
function Homefeed({homeposts,fetchHomePosts}) {
var skipper = 0;
let dispatch = useDispatch()
useEffect(()=>{fetchHomePosts(skipper);},[dispatch]);
function MorePosts(){
console.log(homeposts);
console.log("more");
useEffect(()=>{fetchHomePosts(skipper+10);},[]);
}
return homeposts.isLoading ? (Loading...) : homeposts.error ? ({homeposts.error}) : (
Home Feed
Loading}
next={()=>{MorePosts()}}
>
{
homeposts.homeposts?.map((key,index)=> {
var slug = key.attributes.title;
slug = slug.replace(/\s/g, '-');
slug = slug.toLowerCase();
slug = slug.replace(/[^a-zA-Z0-9\-]/g, '');
slug = slug.replace(/(-)\1+/g, '-');
slug = slug.replace(/-$/, '');
slug = slug.replace(/^-/, '');
return(
)
})
}
)
}
const mapStatetoProps = (state) =>{
return{
homeposts:state.HomePosts
}
}
const mapDispatchtoProps = (dispatch) =>{
return{
fetchHomePosts:(skipper)=>{dispatch(fetchHomePosts(skipper))},dispatch,
}
}
export default connect(mapStatetoProps,mapDispatchtoProps) (Homefeed)
So here the next prop in the Infinite scroll is supposed to call more data which should append to the existing data. The moreposts function should call the api but react gives me an error saying that you cannot call useEffect inside this function.
If i use useDispatch(), its stuck in an infinite loop, can someone please help me out, I'm pretty new to this.
ANSWER
Answered 2021-May-24 at 03:22You cannot call useEffect
inside of another function because this breaks the rules of hooks. But the useEffect
isn't doing anything here. You could just call fetchHomePosts(skipper+10)
from morePosts()
.
That would load the second page. If you want to load the third and the fourth and so on then you need to make skipper
a state rather than a var
. Add 10
to skipper
whenever you load a page.
You can either:
- Increment
skipper
and callfetchHomePosts()
in yourmorePosts()
function. - Increment
skipper
in yourmorePosts()
function and callfetchHomePosts()
from auseEffect
hook which hasskipper
as a dependency so that the effect runs whenever the value ofskipper
changes. - Save the last fetched page number in your Redux store.
- Base the offset on the length of the
homePosts
array.
You don't need to use useDispatch
and connect
. They are two ways of doing the same thing so you should use one or the other. The hooks are the recommended approach.
This is not perfect but I don't want to overcomplicate things:
export default function Homefeed() {
const homeposts = useSelector((state) => state.HomePosts);
const dispatch = useDispatch();
// want to make sure that the first page is loaded when the component mounts
useEffect(() => {
dispatch(fetchHomePosts(0));
}, [dispatch]);
// starts at 0 and increases when more posts load
const dataLength = homeposts.homeposts.length;
// function to load the next page
const morePosts = () => {
dispatch(fetchHomePosts(dataLength));
};
return homeposts.isLoading ? (
Loading...
) : homeposts.error ? (
{homeposts.error}
) : (
Home Feed
Loading}
next={morePosts}
>
{homeposts.homeposts?.map((key, index) => {
// I would store this slug in Redux when you store the post
const slug = key.attributes.title
.replace(/\s/g, "-")
.toLowerCase()
.replace(/[^a-zA-Z0-9-]/g, "")
.replace(/(-)\1+/g, "-")
.replace(/-$/, "")
.replace(/^-/, "");
return (
);
})}
);
}
QUESTION
I just launched my store on wordpress and I ran into a problem: When I am on the home page of the site, all my product titles are in H2 and should be in h3 (SEO reasons), my recommendation products are also in h2 instead of h3 (on the single product page and in collections, i would like to change them all to h3). I looked for a long time where the problem could come from, searched all the files of the theme to change any title from h2 to h3 but nothing helped, I can't find where it is! I also asked the theme creators for help but they told me it was woocomerce's fault and there was nothing they could do ..
A lot of people have had some of the same problem under other themes but they don't have the same "function.php" as me. I also followed this: How can I change the product
in Woocommerce Storefront to ? but it didn't work for me.Can someone help me on this problem ?
here is my "function.php" but i dont think it'll help..
/**
* Theme functions and definitions.
*
* Sets up the theme and provides some helper functions
*
* When using a child theme (see http://codex.wordpress.org/Theme_Development
* and http://codex.wordpress.org/Child_Themes), you can override certain
* functions (those wrapped in a function_exists() call) by defining them first
* in your child theme's functions.php file. The child theme's functions.php
* file is included before the parent theme's file, so the child theme
* functions would be used.
*
*
* For more information on hooks, actions, and filters,
* see http://codex.wordpress.org/Plugin_API
*
* @package OceanWP WordPress theme
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Core Constants.
define( 'OCEANWP_THEME_DIR', get_template_directory() );
define( 'OCEANWP_THEME_URI', get_template_directory_uri() );
/**
* OceanWP theme class
*/
final class OCEANWP_Theme_Class {
/**
* Main Theme Class Constructor
*
* @since 1.0.0
*/
public function __construct() {
// Define theme constants.
$this->oceanwp_constants();
// Load required files.
$this->oceanwp_has_setup();
// Load framework classes.
add_action( 'after_setup_theme', array( 'OCEANWP_Theme_Class', 'classes' ), 4 );
// Setup theme => add_theme_support, register_nav_menus, load_theme_textdomain, etc.
add_action( 'after_setup_theme', array( 'OCEANWP_Theme_Class', 'theme_setup' ), 10 );
// Setup theme => Generate the custom CSS file.
add_action( 'admin_bar_init', array( 'OCEANWP_Theme_Class', 'save_customizer_css_in_file' ), 9999 );
// register sidebar widget areas.
add_action( 'widgets_init', array( 'OCEANWP_Theme_Class', 'register_sidebars' ) );
// Registers theme_mod strings into Polylang.
if ( class_exists( 'Polylang' ) ) {
add_action( 'after_setup_theme', array( 'OCEANWP_Theme_Class', 'polylang_register_string' ) );
}
/** Admin only actions */
if ( is_admin() ) {
// Load scripts in the WP admin.
add_action( 'admin_enqueue_scripts', array( 'OCEANWP_Theme_Class', 'admin_scripts' ) );
// Outputs custom CSS for the admin.
add_action( 'admin_head', array( 'OCEANWP_Theme_Class', 'admin_inline_css' ) );
/** Non Admin actions */
} else {
// Load theme CSS.
add_action( 'wp_enqueue_scripts', array( 'OCEANWP_Theme_Class', 'theme_css' ) );
// Load his file in last.
add_action( 'wp_enqueue_scripts', array( 'OCEANWP_Theme_Class', 'custom_style_css' ), 9999 );
// Remove Customizer CSS script from Front-end.
add_action( 'init', array( 'OCEANWP_Theme_Class', 'remove_customizer_custom_css' ) );
// Load theme js.
add_action( 'wp_enqueue_scripts', array( 'OCEANWP_Theme_Class', 'theme_js' ) );
// Add a pingback url auto-discovery header for singularly identifiable articles.
add_action( 'wp_head', array( 'OCEANWP_Theme_Class', 'pingback_header' ), 1 );
// Add meta viewport tag to header.
add_action( 'wp_head', array( 'OCEANWP_Theme_Class', 'meta_viewport' ), 1 );
// Add an X-UA-Compatible header.
add_filter( 'wp_headers', array( 'OCEANWP_Theme_Class', 'x_ua_compatible_headers' ) );
// Loads html5 shiv script.
add_action( 'wp_head', array( 'OCEANWP_Theme_Class', 'html5_shiv' ) );
// Outputs custom CSS to the head.
add_action( 'wp_head', array( 'OCEANWP_Theme_Class', 'custom_css' ), 9999 );
// Minify the WP custom CSS because WordPress doesn't do it by default.
add_filter( 'wp_get_custom_css', array( 'OCEANWP_Theme_Class', 'minify_custom_css' ) );
// Alter the search posts per page.
add_action( 'pre_get_posts', array( 'OCEANWP_Theme_Class', 'search_posts_per_page' ) );
// Alter WP categories widget to display count inside a span.
add_filter( 'wp_list_categories', array( 'OCEANWP_Theme_Class', 'wp_list_categories_args' ) );
// Add a responsive wrapper to the WordPress oembed output.
add_filter( 'embed_oembed_html', array( 'OCEANWP_Theme_Class', 'add_responsive_wrap_to_oembeds' ), 99, 4 );
// Adds classes the post class.
add_filter( 'post_class', array( 'OCEANWP_Theme_Class', 'post_class' ) );
// Add schema markup to the authors post link.
add_filter( 'the_author_posts_link', array( 'OCEANWP_Theme_Class', 'the_author_posts_link' ) );
// Add support for Elementor Pro locations.
add_action( 'elementor/theme/register_locations', array( 'OCEANWP_Theme_Class', 'register_elementor_locations' ) );
// Remove the default lightbox script for the beaver builder plugin.
add_filter( 'fl_builder_override_lightbox', array( 'OCEANWP_Theme_Class', 'remove_bb_lightbox' ) );
}
}
/**
* Define Constants
*
* @since 1.0.0
*/
public static function oceanwp_constants() {
$version = self::theme_version();
// Theme version.
define( 'OCEANWP_THEME_VERSION', $version );
// Javascript and CSS Paths.
define( 'OCEANWP_JS_DIR_URI', OCEANWP_THEME_URI . '/assets/js/' );
define( 'OCEANWP_CSS_DIR_URI', OCEANWP_THEME_URI . '/assets/css/' );
// Include Paths.
define( 'OCEANWP_INC_DIR', OCEANWP_THEME_DIR . '/inc/' );
define( 'OCEANWP_INC_DIR_URI', OCEANWP_THEME_URI . '/inc/' );
// Check if plugins are active.
define( 'OCEAN_EXTRA_ACTIVE', class_exists( 'Ocean_Extra' ) );
define( 'OCEANWP_ELEMENTOR_ACTIVE', class_exists( 'Elementor\Plugin' ) );
define( 'OCEANWP_BEAVER_BUILDER_ACTIVE', class_exists( 'FLBuilder' ) );
define( 'OCEANWP_WOOCOMMERCE_ACTIVE', class_exists( 'WooCommerce' ) );
define( 'OCEANWP_EDD_ACTIVE', class_exists( 'Easy_Digital_Downloads' ) );
define( 'OCEANWP_LIFTERLMS_ACTIVE', class_exists( 'LifterLMS' ) );
define( 'OCEANWP_ALNP_ACTIVE', class_exists( 'Auto_Load_Next_Post' ) );
define( 'OCEANWP_LEARNDASH_ACTIVE', class_exists( 'SFWD_LMS' ) );
}
/**
* Load all core theme function files
*
* @since 1.0.0oceanwp_has_setup
*/
public static function oceanwp_has_setup() {
$dir = OCEANWP_INC_DIR;
require_once $dir . 'helpers.php';
require_once $dir . 'header-content.php';
require_once $dir . 'oceanwp-strings.php';
require_once $dir . 'oceanwp-theme-icons.php';
require_once $dir . 'customizer/controls/typography/webfonts.php';
require_once $dir . 'walker/init.php';
require_once $dir . 'walker/menu-walker.php';
require_once $dir . 'third/class-gutenberg.php';
require_once $dir . 'third/class-elementor.php';
require_once $dir . 'third/class-beaver-themer.php';
require_once $dir . 'third/class-bbpress.php';
require_once $dir . 'third/class-buddypress.php';
require_once $dir . 'third/class-lifterlms.php';
require_once $dir . 'third/class-learndash.php';
require_once $dir . 'third/class-sensei.php';
require_once $dir . 'third/class-social-login.php';
require_once $dir . 'third/class-amp.php';
require_once $dir . 'third/class-pwa.php';
// WooCommerce.
if ( OCEANWP_WOOCOMMERCE_ACTIVE ) {
require_once $dir . 'woocommerce/woocommerce-config.php';
}
// Easy Digital Downloads.
if ( OCEANWP_EDD_ACTIVE ) {
require_once $dir . 'edd/edd-config.php';
}
}
/**
* Returns current theme version
*
* @since 1.0.0
*/
public static function theme_version() {
// Get theme data.
$theme = wp_get_theme();
// Return theme version.
return $theme->get( 'Version' );
}
/**
* Compare WordPress version
*
* @access public
* @since 1.8.3
* @param string $version - A WordPress version to compare against current version.
* @return boolean
*/
public static function is_wp_version( $version = '5.4' ) {
global $wp_version;
// WordPress version.
return version_compare( strtolower( $wp_version ), strtolower( $version ), '>=' );
}
/**
* Check for AMP endpoint
*
* @return bool
* @since 1.8.7
*/
public static function oceanwp_is_amp() {
return function_exists( 'is_amp_endpoint' ) && is_amp_endpoint();
}
/**
* Load theme classes
*
* @since 1.0.0
*/
public static function classes() {
// Admin only classes.
if ( is_admin() ) {
// Recommend plugins.
require_once OCEANWP_INC_DIR . 'plugins/class-tgm-plugin-activation.php';
require_once OCEANWP_INC_DIR . 'plugins/tgm-plugin-activation.php';
// Front-end classes.
} else {
// Breadcrumbs class.
require_once OCEANWP_INC_DIR . 'breadcrumbs.php';
}
// Customizer class.
require_once OCEANWP_INC_DIR . 'customizer/customizer.php';
}
/**
* Theme Setup
*
* @since 1.0.0
*/
public static function theme_setup() {
// Load text domain.
load_theme_textdomain( 'oceanwp', OCEANWP_THEME_DIR . '/languages' );
// Get globals.
global $content_width;
// Set content width based on theme's default design.
if ( ! isset( $content_width ) ) {
$content_width = 1200;
}
// Register navigation menus.
register_nav_menus(
array(
'topbar_menu' => esc_html__( 'Top Bar', 'oceanwp' ),
'main_menu' => esc_html__( 'Main', 'oceanwp' ),
'footer_menu' => esc_html__( 'Footer', 'oceanwp' ),
'mobile_menu' => esc_html__( 'Mobile (optional)', 'oceanwp' ),
)
);
// Enable support for Post Formats.
add_theme_support( 'post-formats', array( 'video', 'gallery', 'audio', 'quote', 'link' ) );
// Enable support for tag.
add_theme_support( 'title-tag' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
// Enable support for Post Thumbnails on posts and pages.
add_theme_support( 'post-thumbnails' );
/**
* Enable support for header image
*/
add_theme_support(
'custom-header',
apply_filters(
'ocean_custom_header_args',
array(
'width' => 2000,
'height' => 1200,
'flex-height' => true,
'video' => true,
)
)
);
/**
* Enable support for site logo
*/
add_theme_support(
'custom-logo',
apply_filters(
'ocean_custom_logo_args',
array(
'height' => 45,
'width' => 164,
'flex-height' => true,
'flex-width' => true,
)
)
);
/*
* Switch default core markup for search form, comment form, comments, galleries, captions and widgets
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'comment-form',
'comment-list',
'gallery',
'caption',
'widgets',
)
);
// Declare WooCommerce support.
add_theme_support( 'woocommerce' );
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
// Add editor style.
add_editor_style( 'assets/css/editor-style.min.css' );
// Declare support for selective refreshing of widgets.
add_theme_support( 'customize-selective-refresh-widgets' );
}
/**
* Adds the meta tag to the site header
*
* @since 1.1.0
*/
public static function pingback_header() {
if ( is_singular() && pings_open() ) {
printf( '' . "\n", esc_url( get_bloginfo( 'pingback_url' ) ) );
}
}
/**
* Adds the meta tag to the site header
*
* @since 1.0.0
*/
public static function meta_viewport() {
// Meta viewport.
$viewport = '';
// Apply filters for child theme tweaking.
echo apply_filters( 'ocean_meta_viewport', $viewport ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Load scripts in the WP admin
*
* @since 1.0.0
*/
public static function admin_scripts() {
global $pagenow;
if ( 'nav-menus.php' === $pagenow ) {
wp_enqueue_style( 'oceanwp-menus', OCEANWP_INC_DIR_URI . 'walker/assets/menus.css', false, OCEANWP_THEME_VERSION );
}
}
/**
* Load front-end scripts
*
* @since 1.0.0
*/
public static function theme_css() {
// Define dir.
$dir = OCEANWP_CSS_DIR_URI;
$theme_version = OCEANWP_THEME_VERSION;
// Remove font awesome style from plugins.
wp_deregister_style( 'font-awesome' );
wp_deregister_style( 'fontawesome' );
// Load font awesome style.
wp_enqueue_style( 'font-awesome', OCEANWP_THEME_URI . '/assets/fonts/fontawesome/css/all.min.css', false, '5.15.1' );
// Register simple line icons style.
wp_enqueue_style( 'simple-line-icons', $dir . 'third/simple-line-icons.min.css', false, '2.4.0' );
// Register the lightbox style.
wp_enqueue_style( 'magnific-popup', $dir . 'third/magnific-popup.min.css', false, '1.0.0' );
// Register the slick style.
wp_enqueue_style( 'slick', $dir . 'third/slick.min.css', false, '1.6.0' );
// Main Style.css File.
wp_enqueue_style( 'oceanwp-style', $dir . 'style.min.css', false, $theme_version );
// Register hamburgers buttons to easily use them.
wp_register_style( 'oceanwp-hamburgers', $dir . 'third/hamburgers/hamburgers.min.css', false, $theme_version );
// Register hamburgers buttons styles.
$hamburgers = oceanwp_hamburgers_styles();
foreach ( $hamburgers as $class => $name ) {
wp_register_style( 'oceanwp-' . $class . '', $dir . 'third/hamburgers/types/' . $class . '.css', false, $theme_version );
}
// Get mobile menu icon style.
$mobileMenu = get_theme_mod( 'ocean_mobile_menu_open_hamburger', 'default' );
// Enqueue mobile menu icon style.
if ( ! empty( $mobileMenu ) && 'default' !== $mobileMenu ) {
wp_enqueue_style( 'oceanwp-hamburgers' );
wp_enqueue_style( 'oceanwp-' . $mobileMenu . '' );
}
// If Vertical header style.
if ( 'vertical' === oceanwp_header_style() ) {
wp_enqueue_style( 'oceanwp-hamburgers' );
wp_enqueue_style( 'oceanwp-spin' );
}
}
/**
* Returns all js needed for the front-end
*
* @since 1.0.0
*/
public static function theme_js() {
if ( self::oceanwp_is_amp() ) {
return;
}
// Get js directory uri.
$dir = OCEANWP_JS_DIR_URI;
// Get current theme version.
$theme_version = OCEANWP_THEME_VERSION;
// Get localized array.
$localize_array = self::localize_array();
// Comment reply.
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
// Add images loaded.
wp_enqueue_script( 'imagesloaded' );
// Register nicescroll script to use it in some extensions.
wp_register_script( 'nicescroll', $dir . 'third/nicescroll.min.js', array( 'jquery' ), $theme_version, true );
// Enqueue nicescroll script if vertical header style.
if ( 'vertical' === oceanwp_header_style() ) {
wp_enqueue_script( 'nicescroll' );
}
// Register Infinite Scroll script.
wp_register_script( 'infinitescroll', $dir . 'third/infinitescroll.min.js', array( 'jquery' ), $theme_version, true );
// WooCommerce scripts.
if ( OCEANWP_WOOCOMMERCE_ACTIVE
&& 'yes' !== get_theme_mod( 'ocean_woo_remove_custom_features', 'no' ) ) {
wp_enqueue_script( 'oceanwp-woocommerce', $dir . 'third/woo/woo-scripts.min.js', array( 'jquery' ), $theme_version, true );
}
// Load the lightbox scripts.
wp_enqueue_script( 'magnific-popup', $dir . 'third/magnific-popup.min.js', array( 'jquery' ), $theme_version, true );
wp_enqueue_script( 'oceanwp-lightbox', $dir . 'third/lightbox.min.js', array( 'jquery' ), $theme_version, true );
// Load minified js.
wp_enqueue_script( 'oceanwp-main', $dir . 'main.min.js', array( 'jquery' ), $theme_version, true );
// Localize array.
wp_localize_script( 'oceanwp-main', 'oceanwpLocalize', $localize_array );
}
/**
* Functions.js localize array
*
* @since 1.0.0
*/
public static function localize_array() {
// Create array.
$sidr_side = get_theme_mod( 'ocean_mobile_menu_sidr_direction', 'left' );
$sidr_side = $sidr_side ? $sidr_side : 'left';
$sidr_target = get_theme_mod( 'ocean_mobile_menu_sidr_dropdown_target', 'link' );
$sidr_target = $sidr_target ? $sidr_target : 'link';
$vh_target = get_theme_mod( 'ocean_vertical_header_dropdown_target', 'link' );
$vh_target = $vh_target ? $vh_target : 'link';
$array = array(
'isRTL' => is_rtl(),
'menuSearchStyle' => oceanwp_menu_search_style(),
'sidrSource' => oceanwp_sidr_menu_source(),
'sidrDisplace' => get_theme_mod( 'ocean_mobile_menu_sidr_displace', true ) ? true : false,
'sidrSide' => $sidr_side,
'sidrDropdownTarget' => $sidr_target,
'verticalHeaderTarget' => $vh_target,
'customSelects' => '.woocommerce-ordering .orderby, #dropdown_product_cat, .widget_categories select, .widget_archive select, .single-product .variations_form .variations select',
);
// WooCart.
if ( OCEANWP_WOOCOMMERCE_ACTIVE ) {
$array['wooCartStyle'] = oceanwp_menu_cart_style();
}
// Apply filters and return array.
return apply_filters( 'ocean_localize_array', $array );
}
/**
* Add headers for IE to override IE's Compatibility View Settings
*
* @param obj $headers header settings.
* @since 1.0.0
*/
public static function x_ua_compatible_headers( $headers ) {
$headers['X-UA-Compatible'] = 'IE=edge';
return $headers;
}
/**
* Load HTML5 dependencies for IE8
*
* @since 1.0.0
*/
public static function html5_shiv() {
wp_register_script( 'html5shiv', OCEANWP_JS_DIR_URI . 'third/html5.min.js', array(), OCEANWP_THEME_VERSION, false );
wp_enqueue_script( 'html5shiv' );
wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );
}
/**
* Registers sidebars
*
* @since 1.0.0
*/
public static function register_sidebars() {
$heading = get_theme_mod( 'ocean_sidebar_widget_heading_tag', 'h4' );
$heading = apply_filters( 'ocean_sidebar_widget_heading_tag', $heading );
$foo_heading = get_theme_mod( 'ocean_footer_widget_heading_tag', 'h4' );
$foo_heading = apply_filters( 'ocean_footer_widget_heading_tag', $foo_heading );
// Default Sidebar.
register_sidebar(
array(
'name' => esc_html__( 'Default Sidebar', 'oceanwp' ),
'id' => 'sidebar',
'description' => esc_html__( 'Widgets in this area will be displayed in the left or right sidebar area if you choose the Left or Right Sidebar layout.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $heading . ' class="widget-title">',
'after_title' => '',
)
);
// Left Sidebar.
register_sidebar(
array(
'name' => esc_html__( 'Left Sidebar', 'oceanwp' ),
'id' => 'sidebar-2',
'description' => esc_html__( 'Widgets in this area are used in the left sidebar region if you use the Both Sidebars layout.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $heading . ' class="widget-title">',
'after_title' => '',
)
);
// Search Results Sidebar.
if ( get_theme_mod( 'ocean_search_custom_sidebar', true ) ) {
register_sidebar(
array(
'name' => esc_html__( 'Search Results Sidebar', 'oceanwp' ),
'id' => 'search_sidebar',
'description' => esc_html__( 'Widgets in this area are used in the search result page.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $heading . ' class="widget-title">',
'after_title' => '',
)
);
}
// Footer 1.
register_sidebar(
array(
'name' => esc_html__( 'Footer 1', 'oceanwp' ),
'id' => 'footer-one',
'description' => esc_html__( 'Widgets in this area are used in the first footer region.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $foo_heading . ' class="widget-title">',
'after_title' => '',
)
);
// Footer 2.
register_sidebar(
array(
'name' => esc_html__( 'Footer 2', 'oceanwp' ),
'id' => 'footer-two',
'description' => esc_html__( 'Widgets in this area are used in the second footer region.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $foo_heading . ' class="widget-title">',
'after_title' => '',
)
);
// Footer 3.
register_sidebar(
array(
'name' => esc_html__( 'Footer 3', 'oceanwp' ),
'id' => 'footer-three',
'description' => esc_html__( 'Widgets in this area are used in the third footer region.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $foo_heading . ' class="widget-title">',
'after_title' => '',
)
);
// Footer 4.
register_sidebar(
array(
'name' => esc_html__( 'Footer 4', 'oceanwp' ),
'id' => 'footer-four',
'description' => esc_html__( 'Widgets in this area are used in the fourth footer region.', 'oceanwp' ),
'before_widget' => '',
'after_widget' => '',
'before_title' => '<' . $foo_heading . ' class="widget-title">',
'after_title' => '',
)
);
}
/**
* Registers theme_mod strings into Polylang.
*
* @since 1.1.4
*/
public static function polylang_register_string() {
if ( function_exists( 'pll_register_string' ) && $strings = oceanwp_register_tm_strings() ) {
foreach ( $strings as $string => $default ) {
pll_register_string( $string, get_theme_mod( $string, $default ), 'Theme Mod', true );
}
}
}
/**
* All theme functions hook into the oceanwp_head_css filter for this function.
*
* @param obj $output output value.
* @since 1.0.0
*/
public static function custom_css( $output = null ) {
// Add filter for adding custom css via other functions.
$output = apply_filters( 'ocean_head_css', $output );
// If Custom File is selected.
if ( 'file' === get_theme_mod( 'ocean_customzer_styling', 'head' ) ) {
global $wp_customize;
$upload_dir = wp_upload_dir();
// Render CSS in the head.
if ( isset( $wp_customize ) || ! file_exists( $upload_dir['basedir'] . '/oceanwp/custom-style.css' ) ) {
// Minify and output CSS in the wp_head.
if ( ! empty( $output ) ) {
echo "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
} else {
// Minify and output CSS in the wp_head.
if ( ! empty( $output ) ) {
echo "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
}
/**
* Minify the WP custom CSS because WordPress doesn't do it by default.
*
* @param obj $css minify css.
* @since 1.1.9
*/
public static function minify_custom_css( $css ) {
return oceanwp_minify_css( $css );
}
/**
* Save Customizer CSS in a file
*
* @param obj $output output value.
* @since 1.4.12
*/
public static function save_customizer_css_in_file( $output = null ) {
// If Custom File is not selected.
if ( 'file' !== get_theme_mod( 'ocean_customzer_styling', 'head' ) ) {
return;
}
// Get all the customier css.
$output = apply_filters( 'ocean_head_css', $output );
// Get Custom Panel CSS.
$output_custom_css = wp_get_custom_css();
// Minified the Custom CSS.
$output .= oceanwp_minify_css( $output_custom_css );
// We will probably need to load this file.
require_once ABSPATH . 'wp-admin' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'file.php';
global $wp_filesystem;
$upload_dir = wp_upload_dir(); // Grab uploads folder array.
$dir = trailingslashit( $upload_dir['basedir'] ) . 'oceanwp' . DIRECTORY_SEPARATOR; // Set storage directory path.
WP_Filesystem(); // Initial WP file system.
$wp_filesystem->mkdir( $dir ); // Make a new folder 'oceanwp' for storing our file if not created already.
$wp_filesystem->put_contents( $dir . 'custom-style.css', $output, 0644 ); // Store in the file.
}
/**
* Include Custom CSS file if present.
*
* @param obj $output output value.
* @since 1.4.12
*/
public static function custom_style_css( $output = null ) {
// If Custom File is not selected.
if ( 'file' !== get_theme_mod( 'ocean_customzer_styling', 'head' ) ) {
return;
}
global $wp_customize;
$upload_dir = wp_upload_dir();
// Get all the customier css.
$output = apply_filters( 'ocean_head_css', $output );
// Get Custom Panel CSS.
$output_custom_css = wp_get_custom_css();
// Minified the Custom CSS.
$output .= oceanwp_minify_css( $output_custom_css );
// Render CSS from the custom file.
if ( ! isset( $wp_customize ) && file_exists( $upload_dir['basedir'] . '/oceanwp/custom-style.css' ) && ! empty( $output ) ) {
wp_enqueue_style( 'oceanwp-custom', trailingslashit( $upload_dir['baseurl'] ) . 'oceanwp/custom-style.css', false, false );
}
}
/**
* Remove Customizer style script from front-end
*
* @since 1.4.12
*/
public static function remove_customizer_custom_css() {
// If Custom File is not selected.
if ( 'file' !== get_theme_mod( 'ocean_customzer_styling', 'head' ) ) {
return;
}
global $wp_customize;
// Disable Custom CSS in the frontend head.
remove_action( 'wp_head', 'wp_custom_css_cb', 11 );
remove_action( 'wp_head', 'wp_custom_css_cb', 101 );
// If custom CSS file exists and NOT in customizer screen.
if ( isset( $wp_customize ) ) {
add_action( 'wp_footer', 'wp_custom_css_cb', 9999 );
}
}
/**
* Adds inline CSS for the admin
*
* @since 1.0.0
*/
public static function admin_inline_css() {
echo '';
}
/**
* Alter the search posts per page
*
* @param obj $query query.
* @since 1.3.7
*/
public static function search_posts_per_page( $query ) {
$posts_per_page = get_theme_mod( 'ocean_search_post_per_page', '8' );
$posts_per_page = $posts_per_page ? $posts_per_page : '8';
if ( $query->is_main_query() && is_search() ) {
$query->set( 'posts_per_page', $posts_per_page );
}
}
/**
* Alter wp list categories arguments.
* Adds a span around the counter for easier styling.
*
* @param obj $links link.
* @since 1.0.0
*/
public static function wp_list_categories_args( $links ) {
$links = str_replace( ' (', ' (', $links );
$links = str_replace( ' )', ' )', $links );
return $links;
}
/**
* Alters the default oembed output.
* Adds special classes for responsive oembeds via CSS.
*
* @param obj $cache cache.
* @param url $url url.
* @param obj $attr attributes.
* @param obj $post_ID post id.
* @since 1.0.0
*/
public static function add_responsive_wrap_to_oembeds( $cache, $url, $attr, $post_ID ) {...```
ANSWER
Answered 2021-May-19 at 21:08I don't think the functions.php
file has anything to do with it - usually HTML structures like this are created in template php files which are in the themes folder - either on the top level of that folder or as "template parts" in an according subfolder. You have to edit those( or actually those among them that are used by the pages you are referring to), changing all
(also the closing tags).
However, since any not-selfmade theme will be updated every now and then, those changes would be overwritten with updated files when available, it would be necessary to create a child theme, which only contains those templates which you want to change (see also https://developer.wordpress.org/themes/advanced-topics/child-themes/). Then again, updated themes might contain template updates which are necessary, so you'd always have to check which details were updated in that particular template file, integrating it into your child theme templates or editing the updated original themes and using them in your child theme.
P.S.: I think the title of your question is a bit misleading: In the question text you are asking about certain title tags in the product pages, not about parts of the menu, aren't you?
QUESTION
I'm using react-infinite-scroll-component in a project and it works fine outside a Dialog. When I scroll to the bottom of a page, the next set of data is fetched from the server but I can't get the same action inside my Material-UI Dialog.
Here's the Dialog code:
//imports
export default function Posts() {
const [open, setOpen] = React.useState(false);
//more consts
...
const [posts, setPosts] = useState([]);
const [page, setPage] = useState(1);
const fetchPosts = () => {
axios.get(`${serverURL}/news?page=${page}`).then((res) => {
const result = res.data.results;
setPosts([...posts, ...result]);
setPage((prev) => prev + 1);
});
console.log("page", page);
};
useEffect(() => {
fetchPosts();
}, []);
return (
News
Open News Dialog
News
fetchPosts()}
hasMore={true}
loader={Loading.....}
endMessage={
You read all news posts.
}
>
{posts.length > 1 &&
posts.map((post, i) => {
return (
{post.title}
{post.content}
);
})}
);
);
}
The log doesn’t show that I reach the second page, it just stops after I reach the first 30 posts as defined in my backend.
When I test this code outside a Dialog, there are no issues. The infinite scroll works fine on this small text:
function App() {
const [posts, setPosts] = useState([]);
const [page, setPage] = useState(1);
const fetchPosts = () => {
axios
.get(`${serverURL}/api/news?page=${page}`)
.then((res) => {
const result = res.data.results;
setPosts([...posts, ...result]);
setPage((prev) => prev + 1);
});
console.log("page", page);
};
useEffect(() => {
fetchPosts();
}, []);
return (
fetchPosts()}
hasMore={true}
loader={Loading.....}
endMessage={
You read all news posts.
}
>
{posts.length > 1 &&
posts.map((post, i) => (
{post.title}
{post.image}
{post.content}
{post.link}
))}
);
}
export default App;
How Can I get the infinite scroll to work inside a Dialog?
ANSWER
Answered 2021-Jan-01 at 19:31I was able to fix this by adding the scrollableTarget
prop to the DialogContent like this:
fetchPosts()}
hasMore={true}
loader={Loading.....}
endMessage={
You read all new posts.
}
**scrollableTarget="scrollableDiv"**
>
And then added the id="scrollableDiv"
to DialogContent:
...
By default, react-infinite-scroll-component targets the entire window so if you want to apply it to a modal, you must target that window with scrollableTarget
prop.
QUESTION
I am working on a task in which I have to implement infinite scroll paging of 600 dummy records to cards I have coded on FlatList render. So far I have implemented logic using FlatList but not successfully. Help is required where I am doing wrong thus not giving result. Here is the component code:
import React, { Component } from "react";
import { StyleSheet, ActivityIndicator, FlatList, View } from "react-native";
import { Card } from "react-native-elements";
class InfiniteScroll extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
data: [],
dummy: [],
fetchingStatus: false,
setOnLoad: false,
};
this.page = 0;
let onEndReached = false;
}
componentDidMount() {
var toput = [];
for (let i = 0; i < 598; i++) {
toput.push({
name: "KHAN MARKET",
order_no: "ORDER # DBZ-876",
status: "Order Completed",
price: "Total: $14.00",
date: "Dec 19, 2019 2:32 PM",
});
}
this.setState(
{
dummy: toput,
},
() => {
console.log(this.state.dummy);
}
);
this.apiCall();
}
apiCall = () => {
var that = this;
var old = that.page;
that.page = that.page + 10;
console.log(" *********** call " + this.page);
that.setState({ fetchingStatus: true });
that.setState({
data: [...this.state.data, ...this.state.dummy.slice(old, that.page)],
isLoading: false,
fetchingStatus: false,
setOnLoad: true,
});
};
BottomView = () => {
return (
{this.state.fetchingStatus ? (
) : null}
);
};
ItemSeparator = () => {
return (
);
};
render() {
return (
{this.state.isLoading ? (
) : (
index}
data={this.state.data}
ItemSeparatorComponent={this.ItemSeparator}
onScrollEndDrag={() => console.log(" *********end")}
onScrollBeginDrag={() => console.log(" *******start")}
initialNumToRender={8}
maxToRenderPerBatch={2}
onEndReachedThreshold={0.1}
onMomentumScrollBegin={() => {
this.onEndReached = false;
}}
onEndReached={() => {
if (!this.onEndReached) {
this.apiCall(); // on end reached
this.onEndReached = true;
}
}}
renderItem={({ item, index }) => (
{item.name}
{item.order_no}
{item.status}
{item.price}
{item.date}
)}
ListFooterComponent={this.BottomView}
/>
)}
);
}
}
const styles = StyleSheet.create({
textview: {
marginTop: 5,
flexDirection: "row",
justifyContent: "space-between",
},
orderno: {
flexDirection: "row",
justifyContent: "flex-start",
},
orderstatus: {
flexDirection: "row",
justifyContent: "flex-end",
color: "green",
},
ordercomplete: {
flexDirection: "row",
justifyContent: "flex-end",
color: "red",
},
amount: {
justifyContent: "flex-start",
marginTop: 5,
},
});
export default InfiniteScroll;
I will be very thankful if you can provide solution. Thanks
ANSWER
Answered 2021-Apr-19 at 19:08The thing here is that you are seting your dummy data and calling the apiCall
next, the dummy data is not updated yet when you call the apiCall, ande the dummy data is shown as an empty array on the apiCall
, you just ned to force some await before calling the function, just change from this:
this.setState(
{
dummy: toput,
},
() => {
console.log(this.state.dummy);
}
);
this.apiCall();
to this:
this.setState(
{
dummy: toput
},
() => {
this.apiCall();
}
);
Another thing I notice is that you are using some bad pratices like setting valuse direct on the class instead of using state and some messing with the scope (that = this), I've made some updates/suggestions in you code that may help with readability:
apiCall = () => {
const newPage = this.state.page + 10;
this.setState({
data: [
...this.state.data,
...this.state.dummy.slice(this.state.page, newPage)
],
isLoading: false,
fetchingStatus: false,
setOnLoad: true,
page: newPage
});
};
I've created a fully working example so you can see some more updates I've made in the code, that may help you as well:
https://codesandbox.io/s/stackoverflow-67166780-321ku?file=/src/App.js
QUESTION
I am working on a pure JavaScript infinite scroll. I have a 4 list of posts.
I am trying to load more posts (clones of the "original" ones) when I reach the bottom of the container.
class InfiniteScroll {
constructor() {
this.observer = null;
this.isLoading = false;
this.postsContainer = document.querySelector('#postsContainer');
this.postsArary = postsContainer.querySelectorAll('.post');
this.iterationCount = Number(this.postsContainer.dataset.currentPage);
this.perPage = 5;
this.maxCount = this.postsContainer?.dataset?.maxCount;
this.numberOfPages = Math.ceil(this.maxCount / this.perPage);
this.hasNextPage = this.iterationCount < this.numberOfPages;
}
loadMorePosts() {
if (this.hasNextPage) {
this.postsArary.forEach(item => {
let postClone = item.cloneNode(true);
this.postsContainer.appendChild(postClone);
});
} else {
if (this.observer) this.observer.disconnect();
}
}
getLastPost() {
const allPosts = [...this.postsArary];
return allPosts[allPosts.length - 1];
}
counter() {
console.log(this.iterationCount);
if (this.hasNextPage) {
this.iterationCount++;
this.postsContainer.dataset.currentPage = this.iterationCount;
}
this.postsContainer.dataset.hasNextPage = this.hasNextPage;
this.hasNextPage = this.iterationCount < this.numberOfPages;
}
bindLoadMoreObserver() {
if (this.postsContainer) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry && entry.isIntersecting) {
observer.unobserve(entry.target);
this.counter();
this.loadMorePosts();
observer.observe(this.getLastPost());
}
});
});
this.observer.observe(this.getLastPost());
}
}
init() {
this.bindLoadMoreObserver();
}
}
const infiniteScroll = new InfiniteScroll();
infiniteScroll.init();
body, body * {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
.post {
margin: 20px;
padding: 15px;
border: 1px solid #ccc;
border-radius: 5px;
}
p {
line-height: 1.5;
}
Title 1
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
Title 2
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
Title 3
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
Title 4
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
There is an issue with the iterationCount
variable: it does not seem to reach the value 2.
I have not been able to spot the cause of that.
What am I doing wrong?
ANSWER
Answered 2021-Apr-12 at 13:52The array postsArary
is initialized in the constructor and never updated: getLastPost()
always returns the fourth post instead of the last one that was added dynamically. Consequently, the IntersectionObserver
callback is only triggered by the fourth post and not by the one on the bottom of the page.
The updated getLastPost()
method:
getLastPost() {
const allPosts = postsContainer.querySelectorAll('.post');
return allPosts[allPosts.length - 1];
}
This doesn't completely fix the issue. The third page still won't load because counter()
is called before loadMorePosts()
. So for the final page, hasNextPage
is already false
when loadMorePosts()
should still load more posts.
The updated callback:
bindLoadMoreObserver() {
if (this.postsContainer) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry && entry.isIntersecting) {
observer.unobserve(entry.target);
this.loadMorePosts();
this.counter();
if (this.hasNextPage) {
observer.observe(this.getLastPost());
}
}
});
});
this.observer.observe(this.getLastPost());
}
}
QUESTION
I am working on a pure JavaScript infinite scroll.
I have a 4 list of posts. I am trying to load more posts (clones of the "original" ones) when I reach the bottom of the container.
class InfiniteScroll {
constructor() {
this.observer = null;
this.isLoading = false;
this.postsContainer = document.querySelector('#postsContainer');
this.postsArary = postsContainer.querySelectorAll('.post');
this.hasNextPage = this.postsContainer?.dataset?.hasNextPage === 'true';
this.currentPage = this.postsContainer?.dataset?.currentPage;
this.nextPage = this.hasNextPage ? this.currentPage + 1 : null;
}
loadMorePosts() {
if (this.hasNextPage) {
this.postsArary.forEach(item => {
let postClone = item.cloneNode(true);
this.postsContainer.appendChild(postClone);
});
}
}
bindLoadMoreObserver() {
if (this.postsContainer) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry && entry.isIntersecting) {
this.loadMorePosts();
}
});
});
this.observer.observe(this.postsContainer);
}
}
init() {
this.bindLoadMoreObserver();
}
}
const infiniteScroll = new InfiniteScroll();
infiniteScroll.init();
body, body * {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
}
.post {
margin: 20px;
padding: 15px;
border: 1px solid #ccc;
border-radius: 5px;
}
p {
line-height: 1.5;
}
Title 1
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
Title 2
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
Title 3
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
Title 4
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque dolorum consequatur nostrum sapiente ipsa! Veniam, laudantium accusantium, odio maxime quo adipisci possimus enim quam, voluptate quidem animi perferendis delectus aliquam?
The post clones, instead of being appended to the container after scrolling to the last post, are appended when the page loads.
I do not want to use rootMargin
, because it does not seem versatile.
What am I doing wrong?
ANSWER
Answered 2021-Apr-08 at 18:50Ok, maybe it will help someone:
class InfiniteScroll {
constructor() {
this.observer = null;
this.isLoading = false;
this.postsContainer = document.querySelector('#postsContainer');
this.postsArary = postsContainer.querySelectorAll('.post');
this.hasNextPage = this.postsContainer ? .dataset ? .hasNextPage === 'true';
this.currentPage = this.postsContainer ? .dataset ? .currentPage;
this.nextPage = this.hasNextPage ? this.currentPage + 1 : null;
}
loadMorePosts() {
if (this.hasNextPage) {
this.postsArary.forEach(item => {
let postClone = item.cloneNode(true);
this.postsContainer.appendChild(postClone);
});
} else {
if (this.observer) this.observe.disconnect();
}
}
getLastPost() {
const allPosts = [...this.postsContainer.querySelectorAll('.post')];
return allPosts[allPosts.length - 1];
}
bindLoadMoreObserver() {
if (this.postsContainer) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry && entry.isIntersecting) {
observer.unobserve(entry.target);
this.loadMorePosts();
observer.observe(this.getLastPost());
}
});
});
this.observer.observe(this.getLastPost());
}
}
init() {
this.bindLoadMoreObserver();
}
}
const infiniteScroll = new InfiniteScroll();
infiniteScroll.init();
I made the function
getLastPost
- it gets the last of your posts (included added by js).I observe last post, not the whole container
then when this item is intersecting I made 2 things: unobserve current entry element, then after appending new elements I observe the last post- so this will be very last post, added by js.
as bonus in loadMorePosts I saw that you want add posts just when there is next page available.But when not your IO still works, but it's not neccesary (performance). So... disconnect-- disonnect is killing IO process also unobserve all elements in this IO.
QUESTION
I have a function that fetches and dispays data. I need this function to be called twice, once when the page loads and when InfiniteScroll calls it. The problem is that when getData is called by useEffect it goes on forever.
Code:
const getData = async(page) => {
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get(`/api?page=${page}&limit=10`, { cancelToken: source.token })
.then(res => {
setProducts(prevProducts => {
return [...new Set([...prevProducts, ...res.data])]
})
setHasMore(res.data.length > 0)
console.log(res.data)
}).catch(e => {
if (axios.isCancel(e)) return
})
}
useEffect(() => {
getData()
}, [getData])
const handlePagination = () => {
setPage(page + 1)
}
...
...
When getData gets called by useEffect it goes forever. Just to note I'm using react-infinite-scroll-component.
ANSWER
Answered 2021-Apr-03 at 18:06Try to change your useEffect like this
useEffect(() => {
getData(),
return () => {}
}, [])
QUESTION
Hey guys I am trying to implement reverse scroll pagination using InfiniteScroll with package react-infinite-scroll-component but unable to do so. Normal scroll down pagination is working but reverse scroll is not firing the method fetchMoreData2 which I have defined in my script even no error is also been shown. Please guide me.
{this.getList()}
ANSWER
Answered 2021-Mar-01 at 14:22Since I didn't get any guidance or way(I tried with their available properties) to implement reverse scroll pagination using that package so I achieved it in custom way without using that package.
**Putted this line in Constructor**:
this.scrollRef = React.createRef();
**Putted the ref in the scrollable div inside render method**:
//scrollable content
**Putted this line in componentDidMount method**:
this.scrollRef.current.addEventListener("scroll", this.scrollTrackFunc);
**Putted this line in componentDidUnMount method**:
this.scrollRef.current.removeEventListener("scroll", this.scrollTrackFunc);
**Added this method to track reverse scroll**:
scrollTrackFunc = () => {
if (
this.scrollRef!==null && this.scrollRef.current.scrollTop == 0
) {
this.fetchData();
}
}
QUESTION
trying to load youtube comments into a infinite load component (using a npm for it)
the mess happens due to the fact the infinite load component is child of parent Accordion component (from react-bootstrap), and what I'm trying to achieve is fetching with useSWR only if Accordion gets clicked (opened).
What I tried is to use useSWR conditional, so that only fetches when state "show" is true, which is being set inside function:
const showComments = () => {
setShow(true)
if (comments) {
setCommChunks(_.chunk(comments.comm, 10))
setCommList(commChunks[counter])
}
}
called on Accordion.Toggle onClick event.
But what happens is I can only show the comments after I click the Accordion twice, why is that?
My code is:
import { useState, useEffect } from 'react'
import { Row, Col, Button, Accordion } from 'react-bootstrap'
import * as _ from 'lodash'
import useSWR from 'swr'
import { MdUnfoldMore } from 'react-icons/md'
import InfiniteScroll from "react-infinite-scroll-component"
import Comments from './Comments'
const siteurl = process.env.NEXT_PUBLIC_SITE_URL
export default function VideoComments({ video }){
const [show, setShow] = useState(false)
const [counter, setCounter] = useState(0)
const [commList, setCommList] = useState(null)
const [commChunks, setCommChunks] = useState([])
const showComments = () => {
setShow(true)
if (comments) {
setCommChunks(_.chunk(comments.comm, 10))
setCommList(commChunks[counter])
}
}
const fetcher = (...args) => fetch(...args).then(res => res.json())
const { data: comments, error } = useSWR(show ? `${siteurl}/api/c/${video.id}` : null, fetcher)
// useEffect(() => {
// if (comments) {
// commChunks = _.chunk(comments.comm, 10)
// setCommList(commChunks[counter])
// }
// },[comments])
const fetchMoreData = () => {
const newCounter = counter + 1;
// loaded all, return
if (commChunks[newCounter] === undefined || commChunks[newCounter] == null) {
return;
}
const newCommList = [
...commList,
...commChunks[newCounter]
]
setCommList(newCommList)
setCounter(newCounter)
}
return (
{showComments()}} variant="link" eventKey="0">Comments
{commList &&
}
);
}
EDIT: as suggested below I reactivated useEffect, but it still needs two clicks of the Accordion
const showComments = () => {
setShow(true)
if (comments) {
setCommChunks(_.chunk(comments.comm, 10))
setCommList(commChunks[counter])
}
}
const { data: comments } = useSWR(show ? `${siteurl}/api/c/${video.id}` : null, fetcher)
useEffect(() => {
if (comments) {
setCommChunks(_.chunk(comments.comm, 10))
setCommList(commChunks[counter])
}
},[comments])
ANSWER
Answered 2021-Feb-03 at 04:48You commented the useEffect
that handles the comments :
// useEffect(() => {
// if (comments) {
// commChunks = _.chunk(comments.comm, 10)
// setCommList(commChunks[counter])
// }
// },[comments])
What happens :
- You click the Accordion,
showComments
is called show
is set to true, but becausecomments
is undefined,commList
andcommChunks
are not set- the component re-renders, now
useSWR
can use the url to fetch data - the component re-renders when the fetching si done, now
comments
contains the data - You click the Accordion the second time,
showComments
is called show
is set to true, this timecommList
andcommChunks
are set- the component re-renders with
InfiniteScroll
andComments
QUESTION
I'm using nextjs Link with shallow and replace properties to change url from /author
to /author?book=234523452
when the query is detected page conditionally hides an InfiniteScroll component and show a component with a single book instead. Single book component has a "X" to go back (also wrapped within a Link) so to show again the InfiniteScrollComponent.
What I'm trying to do is save the current window Y on query (single book) and when the "X" gets clicked move to that stored position via useState.
I'd like to mention that unfortunately scroll={false} doesn't work for my case.
this is my page relevant code:
const [scrollPos, setScrollPos] = useState()
const readUrl = (url, bool) => {
if (url){
setScrollPos(window.pageYOffset || document.documentElement.scrollTop)
setUrlNow(url)
}else{
router.events.on('routeChangeComplete', () => {
if (typeof window !== "undefined") {
//setTimeout(function(){
window.scrollTo(0,scrollPos)
//},200)
}
})
}
setToggle(bool)
return
}
if (url)
means it's routing from /author
(so with InfiniteScroll component) to /author?book=234523452
(with single book), else
means the "X" got clicked basically and so is routing back to /author
The setTimeout(function()
seems to work most of the times but not always, and also adds an ugly moving effect to it
ANSWER
Answered 2021-Jan-23 at 02:11You can set scrollPos
for reach retainedComponent
and there is detailed guidance here
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install infinitescroll
Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesExplore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits
Save this library and start creating your kit
Share this Page