Лучше передать контекст пользовательскому хуку или вызвать useContext внутри пользовательского хука? - PullRequest
1 голос
/ 13 марта 2019

У меня растет число пользовательских хуков, и многие из них получают доступ к одному и тому же контексту реакции через хук useContext.Во многих компонентах необходимо использовать более одной из этих пользовательских хуков.

Лучше ли вызывать useContext один раз для каждого компонента и передавать контекст в мои пользовательские хуки или лучше вызывать useContext внутри каждого пользовательского крючка?Может не быть правильного или неправильного ответа, но под «лучшим» я подразумеваю, есть ли лучшая практика?Один подход имеет больше смысла, чем другой?

1 Ответ

3 голосов
/ 13 марта 2019

Я бы предложил передать контекст лично: я верю, что это сделает пользовательский хук более понятным, более гибким и более тестируемым.Он отделяет логику, которая работает с данными контекста, от логики, ответственной за получение этих данных.

Ясность

Если вы используете useContext внутри пользовательского хука, это становится неявным контрактом дляловушка: из рассмотрения сигнатуры вызова не ясно, что это зависит от значений из контекста.Явный поток данных лучше, чем неявный поток данных.(Конечно, Context API существует, потому что иногда неявный поток данных полезен, но в большинстве случаев я думаю, что лучше быть явным)

Гибкость

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

const MySpecialCaseComponent = () => {
    const context = useContext(MyContext);
    useMyCustomHook({
       ...context,
       propToOverride: someValue
    });
    return (<div></div>)
}

Это очень неудобно, если пользовательский хук читает прямо из контекста - вам, вероятно, придется ввести новый компонент, завернутый в новыйпоставщик контекста.

Тестируемость

Проще протестировать пользовательский хук, если он не зависит от API контекста.Возможно, в самых простых случаях вы можете просто вызвать свой пользовательский хук с тестовыми данными и проверить возвращаемое значение.

Или вы можете написать тест, например:

test("Test my custom hook", () => {
    const TestComponent = () => {
        useMyCustomHook({ /** test data */ });
        return (/* ... */);
    };
    const element = shallow(<TestComponent />);
    // do testing here
})

Если вы используете контекст в своей ловушке, вам придется визуализировать ваш тестовый компонент внутри <MyContext> провайдера, и этоделает вещи более сложными. Особенно , если вы пытаетесь сделать поверхностный рендеринг (и даже более того, если вы используете react-test-renderer/shallow, , тестирование компонентов с контекстом более сложно .


TL; DR Я не думаю, что это неправильно * от 1034 * до useContext внутри пользовательского хука, но я думаю, что явный поток данных должен быть вашим первым средством для всех обычныхпричины, по которым явный поток данных обычно предпочтительнее неявного потока данных.

...