Как обновить состояние без ввода бесконечного повторного рендеринга l oop в React / Next. js? - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть приложение Next. js, которое воспроизводит случайные видео на YouTube. Мое состояние для приложения выглядит примерно так (в магазине Redux):

const state = {
    entities: {
        videos: {
            'vidId1': {
                id: 'vidId1',
                title: 'Video 1'
            },
            'vidId2': {
                id: 'vidId2',
                title: 'Video 2'
            },
            'vidId3': {
                id: 'vidId3',
                title: 'Video 3'
            }
        }
    },
    uncategorized: {
        isFetching: false,
        hasNextPage: false,
        nextIndex: 0,
        items: [
            'vidId1',
            'vidId2',
            'vidId3'
        ]
    }
};

У меня есть домашняя страница, которая выглядит примерно так:

// index.js
const Index = () => {
    return (
        <div>
            <h1>Home Page</h1>
            <RandomVideoButton />
        </div>
    );
};

<RandomVideoButton /> ссылки на /random. Эта страница просто получает следующий идентификатор видео из штата и перенаправляет на /videos?id={id}. Это выглядит примерно так:

// random.js
const RandomVideo = () => {
    // Get next video ID
    const nextVideoId = useSelector(state => state.uncategorized.items[state.uncategorized.nextIndex]);

    // Redirect to next video
    const router = useRouter();
    router.push({
        pathname: '/videos',
        query: { id: nextVideoId }
    });

    return (
        <div>Loading video...</div>
    );
};

Как только я на /videos?id={id}, эта страница загрузит видео с state.entities.videos, а затем обновит state.uncategorized.nextIdnex. Это где проблема возникает. Когда я отправляю действие для обновления следующего индекса видео в состоянии, я застреваю в бесконечном повторном рендеринге l oop. Вот как выглядит watch.js:

const WatchVideo = () => {
    // Get video ID from URL query
    const router = useRouter();
    const videoId = router.query.id;

    // Get video
    const { video, activeVideos } = useSelector(state => state.entities.videos[videoId]);

    // Update video index
    const dispatch = useDispatch();
    dispatch({ type: 'INCREMENT_NEXT_INDEX' });

    return (
        <div className="col-12 col-lg-8 col-xl-9">
            {video &&
                <main>
                    <div className="embed-responsive embed-responsive-16by9">
                        <iframe id="player" src={'https://www.youtube-nocookie.com/embed/' + video.id}></iframe>
                    </div>
                    <h1>{video.title}</h1>
                </main>
            }
        </div>
    );
};

Моя проблема в том, что я не уверен, как этого избежать, но при этом могу обновлять следующий индекс видео в состоянии.

1 Ответ

1 голос
/ 27 февраля 2020

вы должны использовать диспетчеризацию / маршрутизацию внутри обработчика реакции useEffect. и вы можете использовать videoId как зависимость useEffect.

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