Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应路由器v4。需要防止组件重新渲染(尝试构建类似instagram的图像网格)_Reactjs_React Router - Fatal编程技术网

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

Reactjs 反应路由器v4。需要防止组件重新渲染(尝试构建类似instagram的图像网格),reactjs,react-router,Reactjs,React Router,我创建了一个React应用程序,基本上有3条路线: 根目录/项目:显示产品列表 根目录/items/:itemId:显示产品列表 root/admin:显示管理面板的 我需要什么: 在路径root/items和root/items/:itemId上,我想创造一种与Instagram非常相似的体验: 我希望用户单击任何产品以触发到根/items/:itemId的路由更改,并显示一个模式窗口(显示有关产品的更多信息),而不重新呈现产品列表 当前发生的情况: 每次用户单击产品时 路线更改,将重新呈

我创建了一个React应用程序,基本上有3条路线:

  • 根目录/项目:显示产品列表
  • 根目录/items/:itemId:显示产品列表
  • root/admin:显示管理面板的
我需要什么

在路径root/itemsroot/items/:itemId上,我想创造一种与Instagram非常相似的体验:

我希望用户单击任何产品以触发到根/items/:itemId的路由更改,并显示一个模式窗口(显示有关产品的更多信息),而不重新呈现产品列表

当前发生的情况:

  • 每次用户单击产品时
  • 路线更改,将重新呈现产品列表
  • 并晃动页面,这会影响模式显示
  • 并创造了糟糕的用户体验
  • 有人有主意吗?非常感谢。

    您可以:

    1。使用两条路径渲染相同的组件

    root/items
    root/items/:itemId
    呈现相同的ProductList组件,如果路由中存在
    id
    ,则应在呈现函数中进行检查,并使用信息有条件地呈现模式。您必须在服务器中检查信息,或者,看看如何在官方文档中实现这些信息

    • 根目录/项目:将显示项目
    • root/items/:itemId:相同的组件,但呈现带有信息的模态

    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>
            }
        }
    }
    
    //您在此处导入的内容
    将ProductInfo类作为组件{
    构造函数(){
    this.state={info:{}
    }
    componentDidMount(){
    //使用this.props.id在状态中加载信息和设置信息
    }
    render(){
    //检查信息是否已设置,并按您喜欢的方式呈现所有信息
    返回(){
    {JSON.stringify(this.state.info)}
    }
    }
    }
    
    产品列表

    //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>
            }
        }
    }
    
    //此处导入
    //例如,使用引导导入模式或任意实现
    从“/ProductInfo”导入ProductInfo;
    将ProductList类作为组件{
    构造函数(){
    this.state={infoId:-1}
    }
    变更ID(e){
    //从按下的按钮(或链接或您正在使用的任何组件)获取id
    //在状态中设置id,记住在模式关闭后清除状态:将其设置回-1。
    }
    render(){
    //检查是否设置了id
    设{infoId}=this.state;
    让renderModal=infoId>-1;
    返回(){
    {renderModal&&
    }
    
    • this.changeId(e)}> 信息1
    • this.changeId(e)}> 信息2
    • this.changeId(e)}> 信息3
    } } }
    这是一个简单的例子,有很多更好的方法,但我认为这回答了你的问题

    防止重新渲染组件

    如果在这些建议之后仍要重新渲染,则可能在每次加载信息时都要进行渲染。要防止出现这种情况,请将信息保持在状态,并仅在加载信息时执行条件渲染

    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>
            );
        }
    }
    
    从“/api”导入api;//用于获取数据的自定义api组件
    将ProductList类作为组件{
    构造函数(){
    this.state={list:[],dataLoaded:false,infoId:-1}
    }
    ...
    componentDidMount(){
    让myList=api.getList();//基本上调用获取数据的任何函数
    这是我的国家({
    列表:myList,数据加载:true
    });
    }
    变更ID(e){
    //与前面的示例相同
    }
    render(){
    //仅当使用条件渲染加载数据时才显示渲染列表
    // 
    让{dataLoaded,list,infoId}=this.state;
    让renderModal=infoId>-1;
    返回(
    {renderModal&&
    }
    {已加载数据&&
    
    • //使用状态变量列表在此处呈现列表数据
    } ); } }

    这将阻止重新呈现列表时做出反应,即使您显示了模式。

    您是否尝试过实现shouldComponentUpdate?