React Context API с несколькими значениями производительности - PullRequest
1 голос
/ 18 апреля 2020

Я использую React Context API для хранения многих глобальных значений состояния (около 10 и, вероятно, потребуется больше), и многие компоненты используют их. К сожалению, когда изменяется любое из значений, все компоненты, использующие хук useContext, должны перерисовываться. Мое текущее решение состоит в том, чтобы использовать useMemo для возвращаемого значения компонентов и useCallback для любых сложных функций и внутри пользовательских хуков, которые у меня есть. Это решает большинство моих проблем с производительностью, но необходимость постоянно использовать useMemo и useCallback довольно раздражает, а пропустить один довольно легко. Есть ли более профессиональный способ сделать это?

Вот пример, основанный на моем коде:

GlobalStateContext. js

import React, { useState } from 'react'

const GlobalStateContext = React.createContext({ })

export const GlobalStateProvider = ({ children }) => {
    const [config, setConfig] = useState({
        projectInfo: ''
    })
    const [projectFile, setProjectFile] = useState('./test.cpp')
    const [executionState, setExecutionState] = useState("NoProject")

    return (
        <GlobalStateContext.Provider
            value={{
                executionState,
                config,
                projectFile,
                setExecutionState,
                setConfig,
                setProjectFile,
            }}
        >
            {children}
        </GlobalStateContext.Provider>
    )
}

export default GlobalStateContext

Example.jsx

import React, { useContext } from 'react'
import GlobalStateContext from '../utils/GlobalStateContext.js'

export default Example = () => {
    const {
        executionState,
        setExecutionState,
    } = useContext(GlobalStateContext)

    return useMemo(
        () => (
            <div>
                The current execution state is: {executionState}
                <br />
                <button onClick={() => setExecutionState('Running')}>Running</button>
                <button onClick={() => setExecutionState('Stopped')}>Stopped</button>
                <button onClick={() => setExecutionState('Crashed')}>Crashed</button>
            </div>
        ),
        [
            executionState,
            setExecutionState,
        ]
    )
}

1 Ответ

3 голосов
/ 18 апреля 2020

В настоящее время эта проблема неизбежна в контексте. Существует открытое RF C для селекторов контекста , чтобы решить эту проблему, но в то же время, некоторые обходные пути: useContextSelector и Redux, оба из которых препятствуют рендерингу подписывающего компонента, если данные, которые он читает, не изменились.

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