Кажется, что в вашем примере вы просто экспортируете некоторые вспомогательные функции.И в этом случае использования не может быть никакой разницы между экспортом объекта (с этими функциями) и использованием хука useContext()
.
https://reactjs.org/docs/hooks-reference.html#usecontext
Но из Реагируя на DOCs (ссылка выше), мы получаем, что:
Компонент, вызывающий useContext, всегда будет перерисовываться при изменении значения контекста. Если перерисовывать компонентэто дорого, вы можете оптимизировать его, используя памятку.
Как бы вы этого достигли (перерисовка потребителей), используя экспортируемый объект?
С родительской точки зрения всеэто может вызвать повторную визуализацию дочернего компонента, когда вы визуализируете его с другим props
объектом.И как то, что вы экспортировали, что живет за пределами функции компонента (поскольку вы не можете экспортировать локальные переменные функции и «методы»), сможет изменить объект props
, созданный внутри области действия функции компонента?
TLDR:
Основное отличие состоит в том, что вы не можете вызвать повторный рендеринг дочерних объектов с экспортированным объектом.По крайней мере, не без полного анти-паттерна React.
Представьте, что у вас есть ParentComponent
, который отображает два дорогих дочерних компонента, для которых вы хотите выбрать. И для этого вы будете использовать React.memo()
, поэтому вы будете перерисовывать только те дочерние компоненты, если их props
изменится.
Тот, который использует контекст, будет перерисован, потому что свойство context изменилось, но тот, который использует экспортированную переменную, не будет повторно визуализироваться, потому что все, что изменило, живет вне React.
Пример SandBox: https://vq30v.codesandbox.io/
ParentComponent.js
import React, { useState } from "react";
import SomeContext from "./SomeContext";
import ExpensiveChildComponent from "./ExpensiveChildComponent";
import ExpensiveChildComponentExport from "./ExpensiveChildComponentExport";
let count = null; // VARIABLE THAT WILL BE EXPORTED
console.log("Outside ParentComponent...");
function ParentComponent() {
const [myState, setMyState] = useState(0);
console.log("Rendering Parent Component...");
count = myState; // UPDATING THE EXPORTED VARIABLE
function handleClick() {
setMyState(prevState => prevState + 1);
}
// SETTING UP CONTEXT PROVIDER
return (
<div>
<SomeContext.Provider value={myState}>
<button onClick={handleClick}>Count</button>
<h3>Uses Context</h3>
<ExpensiveChildComponent />
<h3>Uses Exported Object</h3>
<ExpensiveChildComponentExport />
</SomeContext.Provider>
</div>
);
}
console.log("After ParentComponent declaration...");
export { ParentComponent, count }; // EXPORTING COMPONENT AND VARIABLE
ExорогоChildComponent.js (использует контекст)
import React, { useContext } from "react";
import SomeContext from "./SomeContext";
// REACT MEMO WILL ONLY UPDATE IF PROPS OR CONTEXT HAS CHANGED
const ExpensiveChildComponent = React.memo(function ExpensiveChildComponent() {
console.log("Rendering ExpensiveChildComponent...");
const context = useContext(SomeContext);
return <div>{context}</div>;
});
export default ExpensiveChildComponent;
ExорогоChildComponentExport.js (использует экспортированное свойство)
import React from "react";
import { count } from "./ParentComponent"; // IMPORTING THE EXPORTED VARIABLE
console.log("Outside ExpensiveChildComponentExport...");
// REACT MEMO WILL ONLY UPDATE IF PROPS OR CONTEXT HAS CHANGED (AND BOTH ARE NOT BEING USED)
const ExpensiveChildComponentExport = React.memo(
function ChildComponentExport() {
console.log("Rendering ExpensiveChildComponentExport...");
return (
<React.Fragment>
<div>{count}</div>
</React.Fragment>
);
}
);
export default ExpensiveChildComponentExport;
РЕЗУЛЬТАТ:
![enter image description here](https://i.stack.imgur.com/1zdms.gif)
ПРИМЕЧАНИЕ:
Если вы удалите React.memo
из ExpensiveChildComponentExport
, он будет перерисован, потому что React создает новый объект props
на каждомrender (это будет пустой объект, но каждый раз он будет другим).Вот почему я добавил React.memo()
, потому что он будет выполнять поверхностное сравнение с props
объектом.Итак, я могу проиллюстрировать поведение, которое useContext
имеет, а простой экспортируемый объект - нет.