我正在尝试不使用任何状态管理工具(例如Redux)的Hooks,以通过使用类+ redux的传统结构来获得与我相同的行为/结构。
通常,使用类基本代码:
在这里问题出在使用不带Redux的钩子:“与任何组件共享数据”。
以下示例是我通过Hooks在组件之间共享状态的方式:
// app.js
import React, { useReducer } from 'react'
import { BrowserRouter } from 'react-router-dom'
import Routes from '../../routes'
import Header from '../Shared/Header'
import Footer from '../Shared/Footer'
export const AppContext = React.createContext();
// Set up Initial State
const initialState = {
userType: '',
};
function reducer(state, action) {
switch (action.type) {
case 'USER_PROFILE_TYPE':
return {
userType: action.data === 'Student' ? true : false
};
default:
return initialState;
}
}
const App = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<BrowserRouter>
<AppContext.Provider value={{ state, dispatch }}>
<Header userType={state.userType} />
<Routes />
<Footer />
</AppContext.Provider>
</BrowserRouter>
)
}
export default App
// profile.js
import React, { useEffect, useState, useContext} from 'react'
import { URLS } from '../../../constants'
import ProfileDeleteButton from './ProfileDeleteButton'
import DialogDelete from './DialogDelete'
import api from '../../../helpers/API';
// Import Context
import { AppContext } from '../../Core'
const Profile = props => {
// Share userType State
const {state, dispatch} = useContext(AppContext);
const userType = type => {
dispatch({ type: 'USER_PROFILE_TYPE', data: type }); <--- Here the action to call the reducer in the App.js file
};
// Profile API call
const [ profileData, setProfileData ] = useState({});
useEffect(() => {
fetchUserProfile()
}, [])
const fetchUserProfile = async () => {
try {
const data = await api
.get(URLS.PROFILE);
const userAttributes = data.data.data.attributes;
userType(userAttributes.type) <--- here I am passing the api response
}
catch ({ response }) {
console.log('THIS IS THE RESPONSE ==> ', response.data.errors);
}
}
etc.... not important what's happening after this...
现在,我看到userType
值的唯一方法是将其作为道具传递给<Header />
组件。
// app.js
<BrowserRouter>
<AppContext.Provider value={{ state, dispatch }}>
<Header userType={state.userType} /> <--passing here the userType as prop
<Routes />
<Footer />
</AppContext.Provider>
</BrowserRouter>
让我们说我想将userType
的值传递给<Routes />
的子级。
这里是一个例子:
<AppContext.Provider value={{ state, dispatch }}>
<Routes userType={state.userType} />
</AppContext.Provider>
and then, inside <Routes /> ...
const Routes = () =>
<Switch>
<PrivateRoute exact path="/courses" component={Courses} userType={state.userType} />
</Switch>
我不喜欢它。它不是干净,可持续或可扩展的。 关于如何使代码库更好的任何建议?
非常感谢 乔
答案 0 :(得分:0)
您不需要将状态作为道具传递给每个组件。使用上下文,您可以访问父Provider的每个子组件中的化简器中的状态属性。就像您已经在Profile.js中完成
const {state, dispatch} = useContext(AppContext);
这里的状态属性包含化简器中的状态属性。因此,您可以通过 state.userType
来访问它答案 1 :(得分:0)
您需要的一切都在您的上下文之内。
我唯一要做的更改是传播数据,而不是一次尝试访问数据
<AppContext.Provider value={{ ....state, dispatch }}>
然后在您需要访问数据的组件内使用const context = useContext(AppContext)
。
context.userType