Hook
даReact 16.8
новая функция, позволяющая писать безclass
использовать в случае компонентов классаstate
и другиеReact
характеристики; иContext
даReact16.3
представлена новая версияContext API
, в прошломReact
В версии естьContext API
, это закулисная экспериментальная функция, и ее официально предлагается избегать,Redux
Принцип состоит в том, чтобы строить на старомContext API
. новый сейчасContext ApI
Предоставляет метод для передачи данных между деревьями компонентов без ручного добавления свойств для каждого уровня компонентов, открывая новый способ передачи данных.
Введение в контекст
Для того, чтобы решить проблему многоуровневой вложенности между компонентами на разных уровняхprops
Передача данных, этот вид передачи данных очень сложен, и его нелегко поддерживать позже, чтобы избежатьdriling
передача данных, можно использоватьredux
передача данных. в новой версииReact 16.8.6
серединаContext
Принесите нам новый способ общения.
Context API
компонент
-
React.createContext
функция: создатьcontext
контексте параметр является значением по умолчанию (необходимо передатьstate
данные),state
возможноObject、Array
Или существенно типы данных. -
Provider
:Зависит отReact.createContext
Создайте свойство, которое возвращает объект. существуетRedux vs. The React Context APIКитайская метафора похожа на построение дерева компонентов в电子总线
Сравните изображение. -
Consumer
:Зависит отReact.createContext
Создайте свойство, которое возвращает объект. доступ к метафоре电子总线
получить данные.
Context
vs redux
Context
изcontext.Provider/Context.Consumer
а такжеredux
изprovider/connect
очень похожий.Context
Используя шаблон производитель-потребитель, мы можем использовать функции более высокого порядка (Hoc
) имитирует реализациюredux
.
redux
черезdispatch
Одинaction
модифицироватьstore
данные; вReact 16.8.6
версияReact hooks
который предоставилuseredcuers
а такжеuseContext
облегчи нам проходContext+hooks
форму для созданияredux
Context
Простой пример
Context
Он предназначен для обмена данными, которые являются «глобальными» для дерева компонентов, например, текущий аутентифицированный пользователь, тема или предпочитаемый язык.
Class.contextType
Прикреплено кclass
ВверхcontextType
Имущество будет передано другомуReact.createContext()
созданныйContext
объект.这能让你使用this.context
потреблять в последнее времяContext
значение выше. Вы можете получить к нему доступ в любом жизненном цикле, включаяrender
в функции.
Context.Consumer
Позволяет подписаться на функциональные компонентыcontext
. Это требует практики функционирования в детстве. Эта функция получает текущийcontext
значение, возвращаетReact
узел. передается в функциюvalue
Значение эквивалентно переходу вверх по дереву компонентов от этогоcontext
недавнийProvider
который предоставилvalue
стоимость. Если нет соответствующегоProvider
,value
параметр эквивалентен переходу кcreateContext()
изdefaultValue
.
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
// 无论多深,任何组件都能读取这个值。
// 在这个例子中,我们将 “dark” 作为当前的值传递下去。
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// 指定 contextType 读取当前的 theme context。
// React 会往上找到最近的 theme Provider,然后使用它的值。
// 在这个例子中,当前的 theme 值为 “dark”。
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
// 也可以按照这种形式获取
function ThemedButton(){
return (
<ThemeContext.Counsumer>
{theme =>(
<Button theme={theme} />
)
}
</ThemeContext.Counsumer>
);
}
context
Подробное использование см.Контекстная документация
React Hooks
React Hooks
даReact 16.8.6
Версия добавляет выборку в каждом жизненном цикле функциональных компонентов.state
а такжеprops
канал. Позволяет использовать состояние и другие функции React без написания классов. больше не нужно писатьclass
Компоненты, все ваши компоненты будутFunction
. Если вы хотите узнать больше оReact hooks
Информация может относиться кСправочник API хуков.
Базовый API хука
-
useState
: получить компонентstate
Данные о состоянии, первый параметр - это сохраненные данные, второй параметр - это метод рабочих данных, аналогичныйsetState
. доступныйES6
Назначение деструктуризации массива для получения. -
useEffect
: сетевой запрос, подписка на модуль,DOM
операции являются побочными эффектами.useEffect
предназначен для борьбы с побочными эффектами. существуетclass
В компонентах классаcomponentDidMount
а такжеcomponentDidUpdate
Функции жизненного цикла используются для обработки побочных эффектов. -
useContext
:useContext
Легко подписатьсяcontext
изменяет и повторно отображает компонент, когда это необходимо. Например, в функциональном компоненте выше,Consumer
полученный в видеContext
данные, сuseContext
Можно переписать следующим образом:
function ThemedButton(){
const value = useContext(ThemeContxet);
return (
<Button theme={value} />
);
}
useReducers API
если ты привыкнешь к этомуredux
пройти черезreducer
Изменятьstate
илиprops
форму, должно быть легче начатьuseReducers
,useReducers
а такжеuseContext
находится в центре внимания этой статьиAPI
.
-
useReducers
:useReducers
Можно передать три параметра, первый пользовательскийreducer
, второй параметр — это значение по умолчанию для инициализации, а третий параметр — это функция, которая принимает второй параметр для вычисления, чтобы получить значение по умолчанию (необязательно).
const [state,dispatch] = useReducer(reducer,initialValue)
НижеuseReducers
Официальный пример:
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'reset':
return initialState;
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
// A reducer must always return a valid state.
// Alternatively you can throw an error if an invalid action is dispatched.
return state;
}
}
function Counter({initialCount}) {
const [state, dispatch] = useReducer(reducer, {count: initialCount});
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'reset'})}>
Reset
</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
);
}
Простой Редукс
redux
имеютProvider
компоненты, черезstore
передать значение. Здесь мы используемContext
Реализация моделированияProvider
а такжеstore
Передайте значение, полный код может относиться кsimple-redux.
упаковкаProvider
компоненты
в кодеstoreContext
даReact.createContext()
Объект Context, созданный функцией.this.props.store
моделируетсяstore
операции передачи по значению.
import React,{Component} from 'react';
import {storeContext} from './store';
export default class Provider extends Component{
render(){
return (
<storeContext.Provider value={this.props.store}>
{this.props.children}
</storeContext.Provider>
)
}
}
управление данными магазина
store
документы, в том числеreducer
,Context
созданиеinitialState
а такжеreducers
Определение.
import React from 'react';
export const storeContext = React.createContext();
export const initialState = {
user:'kiwis',
age:23
}
export const reducer = (state, action)=>{
switch (action.type) {
case 'CHANGENAME':
return {user:'harhao',age:24}
default:
return initialState;
}
}
Запись App.js
в корневом компонентеApp.js
в использованииReact hooks
д изuseReducer
Функция ловушки, возврат измененийstate
изdispatch
функция. тогда поставьstore
данные иdispatch
перешел в пакетProvider
в компоненте.
import React,{useReducer} from 'react';
import Provider from './views/Provider';
import Child from './views/child';
import {initialState as store,reducer} from './views/store';
import './App.css';
function App() {
const [state,dispatch] = useReducer(reducer,store);
return (
<div className="App">
<Provider store={{state,dispatch}}>
<Child/>
</Provider>
</div>
);
}
export default App;
Пользовательский хук useConnect
существуетuseConext
Оберните слой функций для лучшего моделированияconnect
грамматика. обычай здесьReact hooks
Методы. определить обычайhook
функцияuseConnect
,Следующим образом:
import {useConext} from 'react';
export default function useConnect(props){
return useContext(props);
}
Дочерний компонент
существуетApp.js
подкомпонентChild
в, вredux
прошедшийconnect
Функции высшего порядка для передачи данных. Здесь вы можете использовать пользовательскиеReact hooks
функцияuseConnect
Получатьstate
а такжеdispatch
.
import React,{useContext} from 'react';
import useConnect from './connect';
import {storeContext} from './store';
import DeepChild from './deepChild';
function Child() {
const {state,dispatch}= useConnect(storeContext);
return (
<div className="child">
<p>姓名:{state.user}</p>
<p>年龄:{state.age}</p>
<button onClick={()=>dispatch({type:'CHANGENAME'})}>changeName</button>
<p>deep child:</p>
<DeepChild/>
</div>
);
}
export default Child;
DeepChild (внучатый компонент)
существуетChild
В подкомпонентах импортироватьDeepChild
компоненты. пройти черезuseContext
Получить топ ближайшийstate
данные.
import React,{useContext} from 'react';
import {storeContext} from './store';
import useConnect from './connect';
export default function DeepChild(){
const {state} = useConnect(storeContext);
return (
<div>
{state.user}
</div>
)
}
текущий результат
child
Подкомпоненты иDeepChild
Компонент Sun пройденuseConnect
Получите данные верхнего уровня, окончательный результат работы выглядит следующим образом, вы можете пройтиGitpod
Наблюдайте за исполнением и структурой кода в режиме реального времени
Если вам понравилось, можете поставить лайк~ или звездочку~
гит-адрес:GitHub.com/ha молоко хорошее/простое…
Справочная статья
Реагировать на китайскую документацию
Полное руководство по React Redux 2019
[Перевод] Redux и контекстный API React
Анализ хуков React (Часть 1): Основы
Анализ хуков React (часть 2): продвинутый уровень