React Router v4.Необходимо предотвратить повторный рендеринг компонента (пытаясь построить сетку, похожую на instagram) - PullRequest
0 голосов
/ 08 сентября 2018

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

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

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

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

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

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

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

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

1 Ответ

0 голосов
/ 09 сентября 2018

Вы можете либо:

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

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

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

OR

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

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

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>
        }
    }
}

ProductList

//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 при повторном рендеринге списка, даже если вы покажете модал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...