React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление Firebase в проект React казалось беспорядочным:
- Вариант 1. Создайте компонент более высокого порядка, взаимодействуя с поставщиками и потребителями. Что? Но с Firebase это так просто!
- Вариант 2. Инициализируйте Firebase в отдельном файле, настройте экспорт, включите его в начале проекта, а затем повторно включите в свои компоненты.
И хотя Вариант 1 по-прежнему является более сложным (осмелюсь сказать, лучшим) способом включения Firebase в проект React, который от него зависит, перехватчики React как бы смешивают эти два, но также делают его миллионным. раз чище и проще.
Создание поставщика / потребителя контекста React с помощью крючков React
В этом проекте мы предполагаем, что вашему приложению требуется Firebase для правильной работы. Под этим я подразумеваю: мы предполагаем, что вы хотите, чтобы Firebase была инициализирована в самом верху вашего кода и была доступна вам в любом месте вашего проекта, и что ваше приложение действительно не будет работать (если вообще), если Firebase не работает.
Конечно, это не обязательно. Я инициализирую Firebase таким образом в каждом проекте. Я просто даю вам небольшой контекст (плохая игра слов) относительно того, почему я структурирую это таким образом.
Мы коснемся трех файлов: основного index.js
, нового utils/firebase.js
, который мы создадим, и файла .env.production
.
Перед началом работы: добавьте Firebase в свой проект!
Прежде всего, вы должны убедиться, что добавили в свой проект сам Firebase. Используя npm
, это:
$ npm i firebase
Не используете npm
? Я уверен, ты в этом разберёшься.
Добавление учетных данных Firebase в проект React
Шаг 1 очень простой. Когда вы создаете свой проект Firebase, Firebase предоставляет вам набор учетных данных для подключения к службам. Вам нужно включить их в свой проект React, и лучше всего через ваш .env
файл. В этом случае мы создадим наш .env.production
файл в корне проекта и добавим:
REACT_APP_FIREBASE_API_KEY= REACT_APP_FIREBASE_AUTH_DOMAIN= REACT_APP_FIREBASE_DATABASE_URL= REACT_APP_FIREBASE_PROJECT_ID= REACT_APP_FIREBASE_STORAGE_BUCKET= REACT_APP_FIREBASE_MESSAGING_SENDER_ID= REACT_APP_FIREBASE_APP_ID=
Введите в них свои учетные данные, и вы готовы к шагу №2.
Создание поставщика контекста Firebase
Наш поставщик контекста - это то, что будет «удерживать» наше соединение Firebase и делать его доступным через остальную часть нашего приложения. (Держать - не совсем подходящий термин, но на простом английском языке - вот как вы можете думать об этом, чтобы все это имело смысл.)
На следующем шаге мы инициализируем Firebase. Как только мы это сделаем, нам больше не придется возвращаться и трогать этот файл. Поэтому я считаю это файлом служебной программы и обычно помещаю его в каталог utils
. Следуя этой логике, создайте utils/firebase.js
. (Вы можете называть это как хотите, но лучше быть явным.)
Первый шаг - импортировать в этот файл React и основное приложение Firebase. Мы также собираемся использовать ловушку контекста, поэтому одновременно импортируем useContext
из React:
// utils/firebase.js import React, { createContext } from 'react' import app from 'firebase/app'
Теперь мы создадим нашего поставщика контекста. Мы собираемся инициализировать его значением null
. Вы можете инициализировать его, как хотите, но я начинаю с null
, чтобы позже проверить, существует ли мое соединение, с помощью простого оператора if
. (Я поясню, когда покажу вам, как это сделать, еще в нескольких абзацах.)
Мы также собираемся экспортировать его сюда, чтобы мы могли использовать его в других файлах. Это тоже будет иметь смысл, когда мы перейдем к примеру использования. Но суть в том, что вам нужно экспортировать свой контекст, чтобы использовать его позже в других ваших компонентах.
// utils/firebase.js ... const FirebaseContext = createContext(null) export { FirebaseContext }
И теперь наш последний шаг: мы инициализируем саму Firebase, назначим ее нашему контексту и создадим компонент-оболочку, который мы можем использовать, чтобы обернуть наше приложение и сделать Firebase доступным повсюду.
// utils/firebase.js ... export default ({ children }) => { if (!app.apps.length) { app.initializeApp({ apiKey: process.env.REACT_APP_FIREBASE_API_KEY, authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN, databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL, projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID, storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.REACT_APP_FIREBASE_APP_ID, }) } return ( <FirebaseContext.Provider value={ app }> { children } </FirebaseContext.Provider> ) }
Что ж, это быстро обострилось. Но на самом деле это очень просто. Давайте пройдемся по коду. Во-первых, мы создаем функциональный компонент, который принимает children
в качестве опоры. children
будет остальной частью вашего приложения, и вы увидите это на следующем этапе, когда мы будем использовать этот функциональный компонент.
Затем мы просто инициализируем Firebase, используя их код инициализации. Мне нравится проверять, что оно еще не инициализировано, поэтому я не получаю таких ошибок, как «Попытка инициализировать приложение, но оно уже было инициализировано». Мы используем учетные данные, которые мы добавили в наш .env
файл поэтому мы можем легко переключать учетные данные в зависимости от нашей среды.
Наконец, мы возвращаем компонент, который можно использовать для обтекания всего нашего приложения. Мы присваиваем ему value
из app
, что является нашим инициализированным приложением Firebase. Это то, что мы получим позже, когда вызовем useContext
в приведенном ниже примере.
Обертывание нашего приложения React с помощью нашего нового поставщика контекста Firebase
Последний шаг перед тем, как мы фактически используем Firebase, - это добавление этого нового провайдера в наш проект. Поскольку мы хотим, чтобы он был доступен для всего приложения, я помещу его в основной index.js
файл следующим образом:
// All your other imports like React, React Router, whatever import FirebaseProvider from 'utils/firebase' ReactDOM.render( <FirebaseProvider> <App /> </FirebaseProvider>, document.getElementById('root') )
FirebaseProvider
- это тот функциональный компонент, который мы создали на предыдущем шаге. Поскольку это экспорт по умолчанию из этого файла, вы можете называть его как хотите. Все, что находится внутри FirebaseProvider
, теперь сможет получить доступ к нашему инициализированному приложению Firebase.
Вот и все! Теперь у вас есть Firebase, инициализированная и готовая к использованию в вашем проекте. Давайте посмотрим, как на самом деле это использовать.
Пример использования: получение записей из Firestore для отображения в вашем приложении
Допустим, у нас есть некоторый компонент списка в нашем приложении, и мы хотим получить записи из нашей shirts
коллекции. Здесь мы воспользуемся тремя перехватчиками: useContext
для подключения к Firebase, useState
для обработки нашего списка элементов и useEffect
потому, что мы хотим, чтобы наш компонент отображал начальное состояние, пока мы получаем наши записи.
import React, { useContext, useEffect, useState } from 'react' import { FirebaseContext } from 'utils/firebase' import 'firebase/firestore' export default () => { const firebase = useContext(FirebaseContext) const [list, setList] = useState(null) const ref = firebase.firestore().collection(`shirts`) useEffect(() => { ref.get().then(snapshot => { if (!snapshot) { setList(l => []) } else { let shirts = [] snapshot.forEach(shirt => { shirts.push({ key: shirt.id, ...shirt.data() }) }) setList(l => shirts) } }).catch(error => { // Handle the error }) }, []) let listToDisplay if (list === null) { listToDisplay = (<li>Loading shirts...</li>) } else if (list.length === 0) { listToDisplay = (<li>No shirts found</li>) } else { listToDisplay = list.map(shirt => { return (<li key={ shirt.key }>{ shirt.name }</li>) }) } return ( <ol>{ listToDisplay }</ol> ) }
Я хотел предоставить несколько более подробный пример, чтобы вы могли увидеть его в действии, но основные выводы здесь с точки зрения использования вашего соединения Firebase:
// Import the context we created import { FirebaseContext } from 'utils/firebase' // Import Firestore so this component can use it import 'firebase/firestore' // In your component, get the 'value' (the Firebase app instance) into a variable // You can call it 'firebase', 'app' - whatever you want const firebase = useContext(FirebaseContext)
Хотя может показаться, что это много, это только потому, что мы прошли каждую строчку. На самом деле для создания нашего поставщика контекста Firebase потребовалось всего 27 строк кода (плюс-минус несколько для межстрочного интервала), 3 строки кода для обертывания нашего приложения в Firebase и 3 строки кода для добавления к любому компоненту, в котором вы хотите использовать Firebase. (Плюс несколько .env
записей.)
Дайте мне знать в комментариях, что вы собираетесь построить сейчас, чтобы вы могли легко добавить Firebase в любой проект React с помощью всего нескольких строк повторно используемого кода.