简体   繁体   English

如何使用反应钩子在全局状态的叶值发生变化时有条件地渲染组件

[英]How to render component conditionally when leaf value of global state changes using react hooks

I am attempting to create a hook which allows a component to subscribe to a part of the global state changing.我正在尝试创建一个钩子,它允许组件订阅全局状态更改的一部分。 For example, imagine my state looks like this例如,想象我的状态看起来像这样

{
   products: []
   userForm: {
     name: 'John Smith',
     dateOfBirth: '07/10/1991'
   }
}

The component which controls the dateOfBirth field in the userForm should only re-render if the dateOfBirth field changes.控制 userForm 中dateOfBirth字段的组件应该只在 dateOfBirth 字段更改时重新呈现。

Say I have some global state created using React context.假设我使用 React 上下文创建了一些全局状态。 Here is my attempt at subscribing to the field of the global state that that component cares about这是我订阅该组件关心的全局状态字段的尝试

function useField(field) {
  const [globalState, setGlobalState] = useContext(GlobalState);
  const value = globalState[field] || "initial";
  const setValue = useCallback(
    (value) => {
      setGlobalState((state) => ({
        ...state,
        [field]: value
      }));
    },
    [setGlobalState, field]
  );
  return [value, setValue];
}

Demo https://codesandbox.io/s/dawn-fog-ieqxs?file=/src/App.js:326-612演示https://codesandbox.io/s/dawn-fog-ieqxs?file=/src/App.js:326-612

The above code causes any component which uses the useField hook to rerender.上面的代码会导致任何使用useField钩子的组件重新渲染。

The desired behaviour is that the component should only rerender when that field changes.所需的行为是组件应该只在该字段更改时重新渲染。

It can work, but not with Context API, as for now Context API can't bailout of useless renders.它可以工作,但不能与 Context API 一起使用,因为现在 Context API 无法摆脱无用的渲染。

In other words: components subscribed to context provider will always render on provider value change.换句话说:订阅上下文提供程序的组件将始终在提供程序值更改时呈现。

An example of Context API known problem: Context API 已知问题示例:


const GlobalContext = React.createContext(null);

const InnerComponent = () => {
  /* eslint-disable no-unused-vars */
  const { uselessState } = useContext(GlobalContext);
  console.log(`Inner rendered`);
  return <></>;
};

const InnerMemo = React.memo(InnerComponent);

const InnerComponentUsingContext = () => {
  const { counter, dispatch } = useContext(GlobalContext);
  console.log(`Inner Using Context rendered`);
  return (
    <>
      <div>{counter}</div>
      <button onClick={() => dispatch()}>Dispatch</button>
    </>
  );
};

const InnerComponentUsingContextMemo = React.memo(InnerComponentUsingContext);

const App = () => {
  const [counter, dispatch] = useReducer((p) => p + 1, 0);
  const [uselessState] = useState(null);

  return (
    <GlobalContext.Provider value={{ counter, uselessState, dispatch }}>
      <InnerMemo />
      <InnerComponentUsingContextMemo />
    </GlobalContext.Provider>
  );
};

编辑大上下文问题

That said, using every modern state management solution has a bailout function which will resolve this issue:也就是说,使用每个现代状态管理解决方案都有一个救助功能可以解决这个问题:

// Always renders
const [globalState, setGlobalState] = useContext(GlobalState);
const value = globalState[field] || "initial";

// Bailout, for example with redux
const value = useReducer(globalState => globalState[field], /* Can add bailout function here if necessary */);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何有条件地渲染使用钩子的 React 组件 - How to conditionally render a React component that uses hooks React Hooks:有条件地渲染一个组件,但可以访问整个 state - React Hooks: conditionally render a component but with access to the whole state 使用钩子时如何重新渲染表单值和状态值,并且在不同的组件中更改状态 - How do I rerender form value and state value when using hooks and state is changed in a different component in react 当上下文状态改变时,React 钩子上下文组件不会重新渲染 - React hooks context component doesn't re-render when context state changes 使用全局 Z9ED39E2EA931586B6EZ985A 管理的反应挂钩时,如何将 state 从 class 组件传递到全局 state - How to pass state from class components to global state when using react hooks for global state management props更改时,React钩子不会重新渲染组件 - React hooks doesn't re render component when props changes 当父 state 更改(钩子)时,React 子组件不会更新 - React child component does not update when parent state changes (hooks) 如果 React 中的变量发生变化,如何重新渲染组件(使用 Hooks) - How to re-render a component if a variable changes in React (with Hooks) 如何在useEffect中更新状态的react组件中有条件地呈现? - How to conditionally render in a react component with state updated in useEffect? 如何在使用钩子从子组件获取其值的父组件中更新正确的 state 值反应? - How to update the correct state value in a parent component that gets its value from a child component using hooks in react?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM