Мы можем предотвратить ненужные вычисления для useEffect с пустым массивом в качестве второго аргумента в ловушке:
// that will be calculated every single re-rendering
useEffect(() => {...some procedures...})
// that will be calculated only after the first render
useEffect(() => {...some procedures...}, [])
Но для ловушки useContext, которую мы не можем сделать, как описано выше, предоставьте второй аргумент.Кроме того, мы не можем обернуть useContext с помощью useCallback, useMemo.Например, у нас есть компонент:
const someComponent = () => {
const contextValue = useContext(SomeContext);
const [inputValue, setInputValue] = useState('');
return (
<Fragment>
<input value={inputValue} onChange={onInputChange} />
<span>{contextValue}</span>
</Fragment>
)
Проблема в том, что при каждом наборе текста будет запускаться повторный рендеринг, и у нас будет ненужный повторный рендеринг useContext каждый раз.Одним из решений является торможение компонента на два:
const WithContextDataComponent = () => {
const contextValue = useContext(SomeContext);
return <JustInputComponent contextValue={contextValue} />
const JustInputComponent = (props) => {
const [inputValue, setInputValue] = useState('');
return <input value={inputValue} onChange={onInputChange} />
Итак, теперь проблема исчезла, но два компонента у нас есть.А в верхнем компоненте вместо <SomeComponent />
мы должны импортировать <WithContextDataComponent />
, что, на мой взгляд, немного некрасиво.
Можно ли остановить ненужный повторный рендеринг для useContext без разделения на два компонента?