Javascript 在没有上下文或重复使用缺点的情况下反应全局状态?
我最近浏览了以下文章。自reacts成立以来,人们谈论最多的问题始终是状态管理和全局状态。Redux一直是流行的选择,最近成为了上下文API。但这种方法似乎更简单,代码更少,可扩展性更强 我的问题是,有人能看到使用这种我可能忽略的状态管理方法的不利一面吗。我对代码进行了一些修改,以支持SSR,它可以在Nextjs中工作,并且使操作和状态变量的设置更加友好 代码如下: useGlobalState.jsJavascript 在没有上下文或重复使用缺点的情况下反应全局状态?,javascript,reactjs,redux,react-state-management,Javascript,Reactjs,Redux,React State Management,我最近浏览了以下文章。自reacts成立以来,人们谈论最多的问题始终是状态管理和全局状态。Redux一直是流行的选择,最近成为了上下文API。但这种方法似乎更简单,代码更少,可扩展性更强 我的问题是,有人能看到使用这种我可能忽略的状态管理方法的不利一面吗。我对代码进行了一些修改,以支持SSR,它可以在Nextjs中工作,并且使操作和状态变量的设置更加友好 代码如下: useGlobalState.js import React, { useState, useEffect, useLayout
import React, { useState, useEffect, useLayoutEffect } from 'react';
const effect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
function setState(newState) {
if (newState === this.state) return;
this.state = newState;
this.listeners.forEach((listener) => {
listener(this.state);
});
}
function useCustom() {
const newListener = useState()[1];
effect(() => {
this.listeners.push(newListener);
return () => {
this.listeners = this.listeners.filter((listener) => listener !== newListener);
};
}, []);
return [this.state, this.setState, this.actions];
}
function associateActions(store, actions) {
const associatedActions = {};
if (actions) {
Object.keys(actions).forEach((key) => {
if (typeof actions[key] === 'function') {
associatedActions[key] = actions[key].bind(null, store);
}
if (typeof actions[key] === 'object') {
associatedActions[key] = associateActions(store, actions[key]);
}
});
}
return associatedActions;
}
const useGlobalHook = (initialState, actions) => {
const store = { state: initialState, listeners: [] };
store.setState = setState.bind(store);
store.actions = associateActions(store, actions);
return useCustom.bind(store, React);
};
export default useGlobalHook;
然后为状态变量设置自定义挂钩可以是简单的字符串或对象这里是一个简单的挂钩:
import useGlobalState from './useGlobalState';
const initialState = 'Hi';
// Example action for complex processes setState will be passed to component for use as well
const someAction = (store, val) => store.setState(val);
const useValue = useGlobalState(initialState, { someAction });
export default useValue;
并在组件中使用:
import React from 'react'
import useVal from './useVal'
export default () => {
const [val, setVal, actions] = useVal();
const handleClick = () => {
setVal('New Val');
// or use some actions
actions.someAction('New Val');
}
return(
<div>{val}</div>
<button onClick={handleClick}>Click Me</button>
)
}
从“React”导入React
从“/useVal”导入useVal
导出默认值()=>{
const[val,setVal,actions]=useVal();
常量handleClick=()=>{
setVal(“新Val”);
//或者采取一些行动
actions.someAction(“新Val”);
}
返回(
{val}
点击我
)
}
这似乎是一种更干净、更简单的方法,我想知道为什么这不是react中状态管理的常用方法。首先,您不必将所有内容都打包到提供者中。接下来,它非常容易实现,实际应用程序中涉及的代码更少。有人能看到使用这种方法的缺点吗。我能想到的唯一一件事是上下文api存在的重新呈现问题,但在小范围内这不应该是一个问题。很好的方法,但我仍然认为对于较大的应用程序,
redux
更好,尤其是在性能方面。使用您的方法的一个示例是,将按钮添加为单独的组件,同时使用React.memo
将其包装,并从按钮组件启动actions.toggle()
,但按钮会重新渲染2次,但不会在更改的状态下进行中继
因此,在构建大型应用程序时,您总是希望通过删除不必要的重新渲染来提高性能,但这里的情况并非如此
这是我的分析,谢谢你的工作
这里的代码是一个很好的方法,但我仍然认为,
redux
对于更大的应用程序来说更好,尤其是在性能方面。使用您的方法的一个示例是,将按钮添加为单独的组件,同时使用React.memo
将其包装,并从按钮组件启动actions.toggle()
,但按钮会重新渲染2次,但不会在更改的状态下进行中继
因此,在构建大型应用程序时,您总是希望通过删除不必要的重新渲染来提高性能,但这里的情况并非如此
这是我的分析,谢谢你的工作
这里的代码我使用的是codesandbox的默认react模板,该模板将react.StrictMode包装在index.js中,这导致了双重渲染。如果在index.js中的示例中删除它,它将不会再进行双重渲染。我的意思是
按钮
组件不会在状态上进行中继,因此在使用react.memo
包装它时,当状态更新时,它不应该重新渲染。这里不是这种情况。我使用的是codesandbox的默认react模板,它具有react.StrictMode将应用程序包装在index.js中,这导致了双重渲染。如果在index.js中的示例中删除它,它将不再进行双重渲染。我的意思是,按钮
组件不依赖于状态,因此在使用react.memo
包装它时,当状态更新时,它不应该重新渲染,而这里不是这种情况。