0

I have an array of projects. Each project contains multiple images. By iterating through this array, I display each name. I assigned Link to each item navigation to a path containing the project's name. My intention was to get this name and then display the clicked project's images.

The project page does also contain a next project button - clicking this button will change the path. That's how I get the new project:

cart;
nextCart;

componentDidUpdate(prevProps, prevState, snapshot) {
        const prevPathname = prevProps.location.pathname;
        const pathname = this.props.location.pathname;

        if (pathname !== prevPathname) {
            this.getCarts();
        }
}

getCarts = () => {
        const name = this.props.match.params.name;
        this.cart = this.props.carts.find(value => value.name === name);
        const currentIndex = this.props.carts.findIndex(value => value.name === name);
        const nextIndex = currentIndex < this.props.carts.length - 1 ? currentIndex + 1 : 0;
        this.nextCart = this.props.carts[nextIndex];
};

The problem is, that even though the images change, it happens after a short delay after changing the path. Is there a better way to achieve this behavior?

In other words, when I click the button to change the path, there's a delay until the old project's images disappear and will be replaced with the new.



How I change the path:

this.props.history.push('/project/' + this.nextCart.name);

App.js

function App() {

    ...    

    return (
        <div className="App">
            <Router history={history}>
                <ScrollToTop>
                    <Header/>
                    {projects ?
                        <div>
                            <Route path="/project/:name" component={() => <Project carts={projects}/>}/>
                            <Route path="/about" component={About}/>
                            <div className="hs">
                                <Route path={["/", "/project/:name"]} exact
                                       component={() => <CartHolder carts={projects}/>}/>
                            </div>
                            <div className="hs-mobile">
                                <Route path="/" exact component={() => <CartHolderMobile carts={projects}/>}/>
                            </div>
                        </div>
                        : <div className="black-overlay"/>}
                </ScrollToTop>
            </Router>
        </div>
    )
}
Tom
  • 3,672
  • 6
  • 20
  • 52
  • Difficult to tell without seeing the implmentation of render in ``, but this could be because setting a property on a component (`this.cart =`) won't cause a re render of the component. Calling `setState` will cause a re render. You many want to consider storing some of your information in the components state instead. – Benjamin Parnell Jan 15 '20 at 13:25

1 Answers1

0

It is hard to be certain without a working example to play with, but if it is working after a slight delay it sounds like the image is being loaded from the server (as in, the image hasn't been downloaded yet so you need to wait for the image to be downloaded from the server). Do you have a delay after the initial load of the image? In other words, does the delay persist after displaying the image the first time?

If so, you could try pre-loading the images after you fetch the list. This way they are already loaded on the client and may be rendered immediately.

Hope that helps.

jack.benson
  • 2,211
  • 2
  • 9
  • 17
  • There is solely I a delay changing the data, when it already has been set. In other words, when I click the button to change the path, there's a delay until the old project's images disappear and will be replaced with the new. – Tom Jan 15 '20 at 13:46
  • Is there a delay if you view the same image twice? For example, navigate to an image (delay), navigate to another image (delay), navigate back to the first image (no delay). If this is the case, then the delay is likely caused by waiting for the image to load from the server. Check out the pre-loading example I linked above. – jack.benson Jan 15 '20 at 13:48
  • You were right, it was caused by the images loading. It looked weird since instead of loosing the old image, the image-container component kept the old one until the new one was loaded. I fixed that by setting the src's state to `null` on component update. – Tom Jan 15 '20 at 16:06