Reactjs 我正在使用React上下文,希望确认我的结构
这是我第一个使用带有钩子的react上下文而不是react redux的应用程序,我希望获得应用程序结构的帮助。 (我没有使用react-redux或redux-saga库。)Reactjs 我正在使用React上下文,希望确认我的结构,reactjs,react-hooks,react-context,Reactjs,React Hooks,React Context,这是我第一个使用带有钩子的react上下文而不是react redux的应用程序,我希望获得应用程序结构的帮助。 (我没有使用react-redux或redux-saga库。) 上下文 行动之一就是一个例子 Reducer(index.js):我使用了redux库中的combineReducer函数代码 Root.js import React,{useContext,useReducer}来自“React”; 从“/context”导入AppContext; 从“/reduce
- 上下文
- 行动之一就是一个例子
- Reducer(index.js):我使用了redux库中的combineReducer函数代码
- Root.js
import React,{useContext,useReducer}来自“React”;
从“/context”导入AppContext;
从“/reducers”导入进料器;
从“/actions/clientActions”导入{clientActions}”;
从“/actions/userActions”导入{userActions};
从“/App”导入应用程序;
常量根=()=>{
const initialState=useContext(AppContext);
const[state,dispatch]=useReducer(appeducer,initialState);
const clientDispatch=clientActions(state,dispatch);
const userDispatch=userActions(state,dispatch);
返回(
);
};
导出默认根目录;
因此,每当组件想要访问上下文存储或分派操作时,我都会从组件执行以下操作:
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;
import React,{useContext}来自“React”;
从“./common/ListMenu”导入列表菜单;
从“/List”导入列表;
从“../../context”导入AppContext;
从“./common/Frame”导入框架;
const-Example=props=>{
const{match,history}=props;
const{userState,userDispatch}=useContext(AppContext);
//推送至用户详细信息路由/用户/用户ID
const selectUserList=userId=>{
push(`/user/${userId}`);
userDispatch.clearTabValue(true);
};
返回(
);
};
导出默认示例;
我现在面临的问题是,每当我分派操作或尝试访问上下文存储时,所有组件都会重新呈现,因为上下文提供程序正在包装整个应用程序
我想知道如何修复整个重新渲染问题(如果仍然可以使用我的action/reducer文件夹结构的话)
此外,我正在从动作中获取数据,但我想将其与动作文件分开,就像我们在redux saga结构上所做的一样。我想知道是否有人知道如何在不使用redux/redux saga的情况下将其分离
谢谢,如果您需要任何代码/文件进行检查,请告知我。我曾经遇到过此重新渲染问题,我在官方网站上找到了此信息:
希望它也能对您有所帮助我曾经遇到过这个重新渲染问题,我在官方网站上找到了以下信息: 可能它也会对您有所帮助中描述了此效果(在上下文更新时更新组件) 当上下文值更改时,调用useContext的组件将始终重新呈现。如果重新渲染组件的成本很高,则可以使用记忆功能对其进行优化 可能的解决办法也是如此 我认为普遍的解决方案是
usemo
比如说
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
};
const-Example=props=>{
const{match,history}=props;
const{userState,userDispatch}=useContext(AppContext);
//推送至用户详细信息路由/用户/用户ID
const selectUserList=userId=>{
push(`/user/${userId}`);
userDispatch.clearTabValue(true);
};
const users=userState.users;
返回UseMoom(()=>{
返回
},[users,selectUserList]);//以下是组件所依赖的变量
};
我也可以建议您完全切换到Redux。使用combinereducer
和dispatch
几乎可以做到这一点。React redux现在公开,因此您可以使您的代码非常接近您现在正在做的事情(用useSelector
替换useContext
,用useDispatch
替换useReducer
。这将需要对参数进行微小的更改)中描述了此效果(在上下文更新时更新组件)
当上下文值更改时,调用useContext的组件将始终重新呈现。如果重新渲染组件的成本很高,则可以使用记忆功能对其进行优化
可能的解决办法也是如此
我认为普遍的解决方案是usemo
比如说
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
};
const-Example=props=>{
const{match,history}=props;
const{userState,userDispatch}=useContext(AppContext);
//推送至用户详细信息路由/用户/用户ID
const selectUserList=userId=>{
push(`/user/${userId}`);
userDispatch.clearTabValue(true);
};
const users=userState.users;
返回UseMoom(()=>{
返回
},[users,selectUserList]);//以下是组件所依赖的变量
};
我也可以建议您完全切换到Redux。使用
combinereducer
和dispatch
几乎可以做到这一点。React-redux现在公开,因此您可以使您的代码与您现在所做的非常接近(将useContext
替换为useSelector
并将useReducer
替换为useDispatch
。这需要对参数进行微小的更改)请显示使用上下文从中提取数据的某些组件的代码store@Fyodor嗨,费奥多,谢谢你的评论。我在最后的代码部分添加了。您可以从userDispatch.clearTabValue(true)中看到dispatch;和use state from dataList={userState.users}。请显示使用上下文从中提取数据的某些组件的代码store@Fyodor嗨,费奥多,谢谢你的评论。我在最后的代码部分添加了。您可以从userDispatch.clearTabValue(true)中看到dispatch;并使用statefromdatalist={userState.users}。感谢您的回答@Fyodor。我明白您使用Redux的意思,但如果我继续使用非Redux,您认为将状态/还原器/操作发送给上下文提供程序是正确的方法吗?您认为触发不必要的重新渲染的是什么?如果保持非重新渲染,您仍然可以遵循
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;
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
};