Главная » Статьи » Что React Context API может сделать для вас? Многоязычный текст, модальные элементы и переключатели темы

Что React Context API может сделать для вас? Многоязычный текст, модальные элементы и переключатели темы

Что React Context API может сделать для вас? Многоязычный текст, модальные элементы и переключатели темы

От автора: я ленив, по умолчанию. Изучение чего-то нового требует усилий и времени. Поэтому я всегда начинаю с вопроса: «Почему я должен это изучать? Как этот (нужное подчеркнуть) фреймворк, библиотека, язык программирования облегчат мою жизнь? «

Несколько недель назад я опубликовал руководство и скринкаст о том, как использовать новый React 1.6 Context API. Похоже, что некоторые из читателей js-craft тоже ленивы. В хорошем смысле, конечно :) . Мы получили несколько писем, которые звучат так: «ОК, этот React Context хорош, но как он может пригодиться мне в реальных приложениях? Как я могу использовать React Context API?».

Оказывается, что React Context может использоваться как отличный инструмент для управления «вещами» на глобальном уровне приложения. Например, модалы, открываемые или нет, поддержка нескольких языков, управление идентификацией или переключение темы для сайта, идеально подходят для React Context. В таких ситуациях не имеет смысла возиться со всеми проблемами, связанными с полной настройкой библиотек управления состояниями, таких как Redux или Mobx.

Если это ваша первая встреча с React Context API, может быть хорошей идеей сначала прочитать о том, как его использовать. Официальное руководство вы найдете здесь, и, как было сказано, у нас также есть небольшое пособие на эту тему. Итак, давайте рассмотрим на практике некоторые из вариантов использования React Context.

Создание многоязычного сайта с помощью React Context

Реализация в приложении или на сайте поддержки нескольких языков — утомительная задача, которая обычно попадает в нижнюю часть списка дел. Но для простых вещей, таких как целевые страницы или приложения, которые не очень зависят от текста, React Context может стать отличным инструментом. Ниже у приведен codesandbox с простым примером:

Это точно можно улучшить. Пожалуйста, имейте в виду, что это всего лишь демонстрация концепции.

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

const TranslatableText = props => ( <LanguageConsumer> {({ language }) => props.dictionary[language]} </LanguageConsumer>
); // and to create a TranslatableText
<TranslatableText dictionary={{ french: "Bonjour, Michel!", english: "Hello, Michael!", italian: "Ciao, Michele!"
}}/>

Конечно, все это не сработает, если у нас нет механизма React Context. Во-первых, мы создадим строительные блоки — LanguageContext и LanguageConsumer:

const LanguageContext = React.createContext();
const LanguageConsumer = LanguageContext.Consumer;

Создав их, мы можем теперь построить LanguageProvider. Это стандартный компонент React, который хранит текущий язык приложения и способ обновления этого языка:

 class LanguageProvider extends React.Component { state = { language: "french” }; updateLanguage = e => this.setState({ language: e.target.value }); render() { return ( <LanguageContext.Provider value={{ language: this.state.language, updateLanguage: this.updateLanguage }}> {this.props.children} </LanguageContext.Provider> );}
}

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

const App = () => ( <LanguageProvider> <div> //... </div> </LanguageProvider>
);

И теперь мы можем запускать updateLanguage в заголовке:

const Header = () => { return (<LanguageConsumer> {({ updateLanguage }) => ( <header> see this site in: <select onChange={updateLanguage}> <option value="french">french</option> <option value="english">english</option> <option value="italian">italian</option> </select> </header> )} </LanguageConsumer>);
};

Управление модальными компонентами с помощью контекста React Context

На первый взгляд, получить модальное отображение в приложении React довольно просто. Нам не нужны какие-либо вещи из React Context. Но, когда ваше приложение начнет становиться все больше и сложнее, а модальное состояние применяться повсеместно, появляется смысл использовать React Context.

Ниже вы можете увидеть пример использования контекста React Context для управления модальными компонентами:

Вся магия происходит в компоненте Provider. Он решает, должен ли быть модал открытым и использует компонент оболочки Modal для отображения ModalContent.

class Provider extends React.Component { showModal = (content, props = {}) => { this.setState({ Content, props }); }; hideModal = () => this.setState({ content: null, props: {} }); state = { content: null, props: {}, showModal: this.showModal, hideModal: this.hideModal }; render() { const ModalContent = this.state.content; return ( <ModalContext.Provider value={this.state}> {this.props.children} {ModalContent ? <Modal content={ModalContent} /> : ""} </ModalContext.Provider> ); }
}

Одним из преимуществ является то, что «дизайн» этой системы позволяет нам полностью настраивать то, что входит в контент Modal. Когда вы запускаете создание модального кода, вам нужно будет передать компонент React. Это может быть любой HTML, простой текст, изображение или что-то еще.

const TextModalContent = () => ( <div> <h1>Text modal</h1> <p>Some next here !</p> <CloseButton /> </div>
); const ImageModalContent = () => ( <div> <img src="https://media.makeameme.org/created/take-a-break-09utnz.jpg" /> <CloseButton /> </div>
); //...
<button onClick={() => showModal(TextModalContent)}>Open Modal</button>,
<button onClick={() => showModal(ImageModalContent)}>
Open Image Modal</button>

Компонент Modal служит только как оболочка для ряда классов CSS, чтобы сделать что-то вроде этого.

const Modal = props => { const Content = props.content; return ( <div className="modal"> <div className="modal-content"> <Content /> </div> </div> );
};

Конечно, вы можете улучшить этот пример, задействовав такие функции, как обратный вызов для модальных кнопок «ok-отменить», или параметры, которые могут настраивать некоторые модальные шаблоны. Но, для начала, я думаю, что это довольно неплохо.

Переключение темы с помощью Context React

Мне всегда нравилось, как такие приложения как Twitter или Feedly, дают вам возможность применить на выбор светлую или темную цветовую схему.

И угадай что!? Это довольно легко реализовать с помощью Context React:

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

.day { color: black; background-color: white;
} .night { color: #5692e6; background-color: #142b41;
}

После этого провайдер будет выставлять имя класса CSS и метод для его переключения:

 class TProvider extends React.Component { toggleTheme = evt => { this.setState({ theme: evt.target.checked ? "night" : "day" }); }; state = { theme: "night", toggleTheme: this.toggleTheme }; //..
}

Метод toggleTheme будет вызываться, когда пользователь изменяет статус слайдера темы:

class Slider extends React.Component { render() { return ( <label className="switch"> <TConsumer> {({ toggleTheme, theme }) => ( <input onChange={toggleTheme} type="checkbox" checked={theme === "night"} />)} </TConsumer>
//...

И учитывая тот факт, что значение состояния theme Context Provider задано как className главного div нашего приложения, это также обновит вид приложения:

 const App = () => ( <TProvider> <TConsumer> {({ theme }) => ( <div className={theme}> <h1>React Context</h1>
//...

Вы также можете найти другие практические применения для React Context. Однако имейте в виду, что React Context — это приемлемое решение в основном для простых случаев. React Context не (или, по крайней мере, пока не) предназначен для решений сложного управления состояниями. Есть случаи, когда для вашего приложения лучше использовать Redux или Mobx, но для простых вещей нет смысла добавлять этот дополнительный код, и вы можете просто использовать встроенный React Context.

Источник: http://www.js-craft.io/

Редакция: Команда webformyself.