react的useContext
useContext
是 React 中的一个 Hook,用于在函数组件中访问上下文(Context)。它可以让你轻松地共享状态或数据,而不需要通过 props 一层一层传递。- 通过
useContext
,可以有效地管理状态和数据,提高代码的可维护性和可读性。当上下文的值变化时,所有使用该上下文的组件都会自动重新渲染。
// This will technically work if you give a Consumer<T> or Provider<T> but it's deprecated and warns
/**
* Accepts a context object (the value returned from `React.createContext`) and returns the current
* context value, as given by the nearest context provider for the given context.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usecontext
*/
function useContext<T>(context: Context<T>/*, (not public API) observedBits?: number|boolean */): T;
useContext基本用法
1. 创建 Context:
首先,你需要创建一个 Context 对象。
import React, { createContext } from 'react';
const MyContext = createContext();
2. 提供 Context:
在组件树的某一层使用 MyContext.Provider
来提供上下文值。
const App = () => {
const value = "Hello, World!";
return (
<MyContext.Provider value={value}>
<ChildComponent />
</MyContext.Provider>
);
};
3. 消费 Context:
在子组件中,使用 useContext
来获取上下文的值。
import React, { useContext } from 'react';
const ChildComponent = () => {
const value = useContext(MyContext);
return <div>{value}</div>; // 输出: Hello, World!
};
Control Center的状态管理对象StateProvider
1. 创建 Context:
import React, { createContext, useReducer, useContext } from 'react'
export const StateContext = createContext()//创建全局的环境对象
2. 提供 Context:
- 通过Context对象的Provider函数提供状态值
export const StateProvider = ({ reducer, initialState, children }) => (
// 对所有组件进行包裹,对象value为共享数据
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
)
- 此代码通过Reducer 进行状态管理,状态值value通过
useReducer
函数获取,:
const [state, dispatch] = useReducer(reducer, initialState);
- useReducer 接受 reducer 函数(它接收当前状态和一个动作,并返回新的状态) 和 初始状态(用于初始化状态)
- 返回:当前的状态state和用于发送动作以更新状态的dispatch函数。下面是一个useReducer使用示例:
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
- App.js通过StateProvider 标签向DOM传入初始状态和状态更改函数reducer
<StateProvider initialState={initialState} reducer={reducer}> // reducer函数接收当前的 state 和一个 action,并根据 action 的类型返回新的状态对象
<Pane background='tint1' height='100%'> // 创建一个背景为'tint1'且高度为100%的容器
……
</Pane>
</StateProvider>
3. 消费 Context:
// useContext(环境对象)
export const useStateValue = () => useContext(StateContext)
export const actions = {
DB: {
OPEN_CREATEDB_DIALOG: 'OPEN_CREATEDB_DIALOG', CLOSE_CREATEDB_DIALOG: 'CLOSE_CREATEDB_DIALOG', OPEN_ADDDB_DIALOG: 'OPEN_ADDDB_DIALOG', CLOSE_ADDDB_DIALOG: 'CLOSE_ADDDB_DIALOG', SET_DB: 'SET_DB'
},
SYSTEMS: {
SET_IPFS: 'SET_IPFS', SET_ORBITDB: 'SET_ORBITDB'
},
PROGRAMS: {
SET_PROGRAMS: 'SET_PROGRAMS', SET_PROGRAMS_LOADING: 'SET_PROGRAMS_LOADING', SET_PROGRAM: 'SET_PROGRAM', SET_PROGRAM_LOADING: 'SET_PROGRAM_LOADING'
}
}
export const loadingState = 'loading'
- 在
\src\components\CreateDialog.js
的<Dialog />
标签中使用和更新状态:
import { useStateValue, actions } from '../state'
const [appState, dispatch] = useStateValue()
dispatch({ type: actions.DB.CLOSE_ADDDB_DIALOG }) // 关闭Dialog时运行dispatch更改状态
dispatch({ type: actions.DB.CLOSE_CREATEDB_DIALOG })//点击上传时运行dispatch更改状态