A
A
Alexander1992021-01-18 20:12:41
React
Alexander199, 2021-01-18 20:12:41

How to implement animation in the actual page when navigating?

I want to implement the functionality as in dtf , where between the transitions over the pages, the loading animation under the Header in the actual page is triggered.

But I don't quite understand why it has such an effect. Obviously, there are not standard NavLinks here, because when you use it, you immediately jump to another page.

As I understand it, this effect is achieved using useHistory when, with a get request, animation is first turned on, and then when the data has arrived successfully, does it throw you?

Unfortunately, I do not have the opportunity to test this theory now, but the question still does not let me go.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Valery Kulakov, 2021-01-19
@Alexandr199

Obviously, there are not standard NavLinks here, because when you use it, you immediately jump to another page.

You're right. There are several possible reasons why this happens:
  • Dynamic Import
  • Data Preload

This can be implemented in two ways:
  1. Something to do with NavLink
  2. Do something with the router

Pre-import - when we do not know in advance the component that needs to be loaded, it is implemented through , and "import" as a function: . Conceptual example (and sandbox link ):<React.Suspense fallback={<>Loading...</>}>React.lazy()import('./ImportedPage')
// index.jsx
// "const Page = ..." - это концепция, в реальности в роутере
// можно получить название страницы (или id), которые и будут названием файла.

import React from 'react';

function App() {
  const Page = React.lazy(() => import('./ImportedPage'))
  return (
    <div>
      <React.Suspense fallback={<>Loading...</>}>
        <Page />
      </React.Suspense>
    </div>
  );
}
export default App;

// ImportedPage.jsx, то что импортирует главный компонент.

import React from 'react';

function Page() {
  return (
    <div>
      <h1>Some Page, preloading required</h1>
    </div>
  );
}

export default Page;

Instead of "<>Loading...>" you can implement "loading bar".
The second option is to preload the data. Let's say a component (the page we're going to go to) needs data from the server (say, a list of jobs with pictures). So, first we request data from the server, show the preloader (in your case, the loading bar), and only when the data is received, show the finished page. If you use redax, then when sending an asynchronous action, you can post something like "LOADING_BAR_SHOW" to the reducer, and after the data is loaded (when the server response is received) - two actions, like "PAGE_SHOW" (with payload, by which you can determine the required page ) and "LOADING_BAR_CLOSE" (which will hide the loading bar).
Let's also look at the implementation of changing the behavior of NavLink . When clicking, we do preventDefault, after which we perform the necessary operations (dynamic imports, requests to the server, whatever), and when this is done, we push the URL to history. I got something like this ( link to the sandbox ):
import React from 'react';
import { Switch, Route, Link, useHistory } from 'react-router-dom';
import BarLoader from 'react-bar-loader';


export default () => {

  const [data, setData] = React.useState();
  const [isLoading, toggleLoading] = React.useState(false);
  const history = useHistory();

  const getData = () => (
    new Promise((res, rej) => {
      // Здесь можем выполнять любую нужную операцию - например, запрос к серверу
      setTimeout(() => res('Some data, may be from server...'), 2000);
    }).then(data => setData(data))
  );

  const handleLinkClick = (e) => {
    toggleLoading(true)
    e.preventDefault();
    const pathname = e.target.pathname;
    getData()
      .then(data => {
        toggleLoading(false)
        history.push(pathname)
      })
  };

  // Просто обертка над Link, чтобы не писать всегда onClick={handleLinkClick}
  const WaitingLink = (props) => <Link onClick={handleLinkClick} {...props}>{props.children}</Link>

  return (
    <div>
      <header>
        {
          isLoading && <BarLoader color='#1D8BF1' height='3' />
        }
        <ul>
          <li><WaitingLink to={'/'}>Home Page</WaitingLink></li>
          <li><WaitingLink to={'/somepage'}>Some Other Page</WaitingLink></li>
          <li><WaitingLink to={'/somepage2'}>Some Other Page 2</WaitingLink></li>
        </ul>
      </header>
      <Switch>
        <Route exact path={'/'}>
          <div style={{background: '#ff8888'}}>
            <h1>Home Page</h1>
          </div>
        </Route>
        <Route exact path={'/somepage'}>
          <div style={{background: '#88ff88'}}>
            <h1>Some Other Page</h1>
          </div>
        </Route>
        <Route exact path={'/somepage2'}>
          <div style={{background: '#8888ff'}}>
            <h1>Some Other Page 2</h1>
            {/*Попробуем данные из состояния взять, которые получены при клике*/}
            {/*В реальности это может быть redux-srore*/}
            <p>{data ? data : (getData(), null)}</p>
          </div>
        </Route>
      </Switch>
    </div>
  );
};

A
Anton Mudrenok, 2017-05-19
@mr_drinkens89

When you create a reducer, you can set any initialState. Example in the doc :

import { VisibilityFilters } from './actions'

const initialState = {
  visibilityFilter: VisibilityFilters.SHOW_ALL,
  todos: []
}

function todoApp(state, action) {
  if (typeof state === 'undefined') {
    return initialState
  }

  // For now, don't handle any actions
  // and just return the state given to us.
  return state
}

Here, instead of an empty array, in your case it will be filled.

K
KnightForce, 2017-05-19
@KnightForce

The dude above is right, but you can leave it like this:

{
 oneListOfObjects:[],
 twoListOfObjects:[],
 threeListOfObjects:[],
}

And then, for example, in constructor App (or whatever wraps your Provider there ), call a request to the server. Here it is as you wish. For example, if you need to rewrite in React, but not rewrite the server.
initState is the initial store for your project.
You can use one reducer and refer to certain store fields in it , but to make it easier, they are split. As a result, each reducer works with its own field from the store.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question