反应路由器v4。需要防止组件重新渲染(尝试构建类似instagram的图像网格)

问题描述 投票:0回答:1

我创建了一个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. 并创造了糟糕的用户体验

有人有想法吗?非常感谢你。

reactjs react-router
1个回答
2
投票

你可以:

1.使用2个路径渲染相同的组件

root/itemsroot/items/:itemId都呈现相同的ProductList组件,如果路径中的id存在,则应检查渲染函数,并有条件地渲染带有info的模态。您必须在componentDidMount()shouldComponentUpdate()中检查服务器中的信息,看看如何在官方文档中实现这些信息。

  • root / items:将显示项目
  • root / items /:itemId:相同的组件,但使用info呈现模式。

要么

2.不要使用路由,有条件地渲染另一个组件

您可以拥有一个自定义组件(ProductInfo),该组件将产品的ID作为道具接收并呈现产品的信息。在ProductInfo的componentDidMount()函数中,您可以查询服务器以获取信息并显示它。现在,在产品列表组件(ProductList)中,您可以使用在props中传递的id对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重新呈现列表。

© www.soinside.com 2019 - 2024. All rights reserved.