这是我的第一个使用带有钩子的react上下文而不是react-redux的应用程序,希望获得应用程序结构的帮助。 (我不使用react-redux或redux-saga库。)
const AppContext = createContext({
client,
user,
});
export const userActions = (state, dispatch) => {
function getUsers() {
dispatch({ type: types.GET_USERS });
axios
.get("api address")
.then(function(response) {
dispatch({ type: types.GOT_USERS, payload: response.data });
})
.catch(function(error) {
// handle error
});
}
return {
getUsers,
};
};
const AppReducer = combineReducers({
client: clientReducer,
user: userReducer,
});
import React, { useContext, useReducer } from "react";
import AppContext from "./context";
import AppReducer from "./reducers";
import { clientActions } from "./actions/clientActions";
import { userActions } from "./actions/userActions";
import App from "./App";
const Root = () => {
const initialState = useContext(AppContext);
const [state, dispatch] = useReducer(AppReducer, initialState);
const clientDispatch = clientActions(state, dispatch);
const userDispatch = userActions(state, dispatch);
return (
<AppContext.Provider
value={{
clientState: state.client,
userState: state.user,
clientDispatch,
userDispatch,
}}
>
<App />
</AppContext.Provider>
);
};
export default Root;
因此,每当组件想要访问上下文存储或调度动作时,这就是我从组件执行的操作:
import React, { useContext } from "react";
import ListMenu from "../common/ListMenu";
import List from "./List";
import AppContext from "../../context";
import Frame from "../common/Frame";
const Example = props => {
const { match, history } = props;
const { userState, userDispatch } = useContext(AppContext);
// Push to user detail route /user/userId
const selectUserList = userId => {
history.push(`/user/${userId}`);
userDispatch.clearTabValue(true);
};
return (
<Frame>
<ListMenu
dataList={userState.users}
selectDataList={selectUserList}
/>
<List />
</Frame>
);
};
export default Example;
我现在面临的问题是,每当我调度操作或尝试访问上下文存储时,由于上下文提供者包装了整个应用程序,所有组件都将重新呈现。
我想知道如何解决整个重新渲染问题(如果仍然可以使用我的action / reducer文件夹结构)。
此外,我正在从操作中获取数据,但我想将其与操作文件分开,就像我们在redux-saga结构上所做的一样。我想知道是否有人知道如何在不使用redux / redux-saga的情况下将其分开。
谢谢,如果您需要任何代码/文件来检查,请告诉我。
答案 0 :(得分:0)
我曾经遇到过此重新渲染问题,并且在官方网站上找到了以下信息: https://reactjs.org/docs/context.html#caveats 也许它也会对您有帮助
答案 1 :(得分:0)
此效果(更新上下文更新中的组件)在official documentation中进行了描述。
可能的解决方案当上下文值更改时,调用useContext的组件将始终重新呈现。如果重新渲染组件的成本很高,则可以使用备注对其进行优化
我认为通用解决方案是useMemo
例如
const Example = props => {
const { match, history } = props;
const { userState, userDispatch } = useContext(AppContext);
// Push to user detail route /user/userId
const selectUserList = userId => {
history.push(`/user/${userId}`);
userDispatch.clearTabValue(true);
};
const users = userState.users;
return useMemo(() => {
return <Frame>
<ListMenu
dataList={users}
selectDataList={selectUserList}
/>
<List />
</Frame>
}, [users, selectUserList]); // Here are variables that component depends on
};
我还建议您完全切换到Redux。您几乎可以使用combineReducers
和dispatch
。 React-redux现在公开了useDispatch
and useSelector
hooks,因此您可以使您的代码非常接近您正在做的事情(用useContext
替换useSelector
,用{{1}替换useReducer
}。这将需要对参数进行较小的更改)