React Router v4. Необходимо предотвратить повторный рендеринг компонента (попытка создания сетки изображений, подобной Instagram)

Я создал приложение React, которое в основном состоит из трех маршрутов:

  • корень / элементы: отображает список продуктов.
  • корень / предметы /: itemId: отображает список продуктов.
  • root / admin: отображает админку

Что мне нужно:

На маршрутах корень / элементы и корень / предметы /: itemId я хотел бы создать опыт, очень похожий на то, что делает Instagram: https://www.instagram.com/p/BjXyK9WAEjH/?taken-by=amazon

Я бы хотел, чтобы пользователь щелкнул любой продукт, чтобы вызвать изменение маршрута на корень / предметы /: itemId и появилось модальное окно (для отображения дополнительной информации о продукте) БЕЗ ПЕРЕДАЧИ ПЕРЕПРОДАЖА СПИСКА ТОВАРОВ.

Что сейчас происходит:

  1. Каждый раз, когда пользователь нажимает на продукт
  2. Смена маршрута, который повторно рендерит список товаров
  3. и качает страницу, что мешает модальному отображению
  4. и создает плохой пользовательский опыт

Есть у кого-нибудь идеи? Большое тебе спасибо.

Вы пробовали реализовать shouldComponentUpdate?

Jan Peter 08.09.2018 16:15
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
1
3 505
1

Ответы 1

Вы могли либо:

1. Используйте 2 маршрута для рендеринга одного и того же компонента.

как root/items, так и root/items/:itemId визуализируют один и тот же компонент ProductList, вам следует проверить в функции визуализации, существует ли id в маршруте, и условно визуализировать модальное окно с информацией. Вы должны проверить информацию на своем сервере в componentDidMount () или shouldComponentUpdate (), посмотрите, как их реализовать, в официальных документах.

  • root / items: отобразит элементы
  • root / items /: itemId: тот же компонент, но отображает модальное окно с информацией.

ИЛИ

2. Не используйте маршруты, условный рендеринг другого компонента.

У вас может быть собственный компонент (ProductInfo), который получает идентификатор продукта в качестве реквизита и отображает информацию о продукте. В функции componentDidMount () ProductInfo вы можете запросить свой сервер, чтобы получить информацию и отобразить ее. Теперь в компоненте списка продуктов (ProductList) вы можете выполнить условную визуализацию ProductInfo с идентификатором, переданным в реквизитах.

Информация о продукте

// your imports here
class ProductInfo as Component {
    constructor(){
        this.state = {info:{}}
    }

    componentDidMount(){
        // load info and set info in state using this.props.id
    }

    render(){
        // check if info is set and render all the info however you like
        return(){
            <div>{JSON.stringify( this.state.info )}</div>
        }
    }
}

Список продуктов

//imports here
//import a Modal, or implement however you like, with bootstrap for example
import ProductInfo from './ProductInfo';

class ProductList as Component {
    constructor(){
        this.state = {infoId: -1}
    }

    changeId(e){
        // get the id from the pressed button (or link or whatever component you are using)
        // set the id in the state, remember to clean the state after the modal has been closed: set it back to -1.
    }

    render(){
        // check if id is set
        let {infoId} = this.state;
        let renderModal = infoId > -1;
        return(){
            <div>
                {renderModal &&
                    <Modal>
                        <ProductInfo id = {infoId}/>
                    </Modal>
                }
                <ul>
                    <li>
                        <button
                            type = {'button'}
                            name = {'id1'}
                            onChange = {(e) => this.changeId(e)}>
                            Info 1
                        </button>
                    </li>
                    <li>
                        <button
                            type = {'button'}
                            name = {'id2'}
                            onChange = {(e) => this.changeId(e)}>
                            Info 2
                        </button>
                    </li>
                    <li>
                        <button
                            type = {'button'}
                            name = {'id3'}
                            onChange = {(e) => this.changeId(e)}>
                            Info 3
                        </button>
                    </li>
                </ul>
            </div>
        }
    }
}

Это простой пример, есть много способов сделать это лучше, но я думаю, что это ответ на ваш вопрос.

Предотвращение повторного рендеринга компонентов

Если после этих предложений повторный рендеринг все еще продолжается, возможно, вы выполняете рендеринг каждый раз при загрузке информации. Чтобы предотвратить это, сохраняйте информацию в состоянии и выполняйте условную визуализацию только тогда, когда информация загружена.

import api from './api'; // your custom api component to get data

class ProductList as Component {
    constructor(){
        this.state = {list:[], dataLoaded: false, infoId:-1}
    }

    ...

    componentDidMount(){
        let myList = api.getList(); // basically call any function that gets your data
        this.setState({
            list:myList , dataLoaded: true
        });
    }

    changeId(e){
        // same as previous example
    }

    render(){
        // only render list if data is loaded using conditional rendering
        // 
        let {dataLoaded, list, infoId} = this.state;
        let renderModal = infoId> -1;

        return(
            <div>
                {renderModal &&
                    <Modal>
                        <ProductInfo id = {infoId}/>
                    </Modal>
                }
                {dataLoaded &&
                    <ul>
                        <li>

                        // render your list data here using the variable list from the state

                        <li>
                    </ul>
                }
            </div>
        );
    }
}

Это предотвратит повторное рендеринг списка в React, даже если вы показываете модальное окно.

Другие вопросы по теме