首页 > 解决方案 > 反应组件子不渲染

问题描述

我有一个 React 组件,它在每次渲染时迭代其数组refs.current并返回对应于该数组的 JSX 元素refs.current数组。

我将数组refs.current视为伪状态。无论如何它通常工作正常,但我得到了这个奇怪的情况,它不会更新子组件。

我什至在 return 语句中写了一个控制台日志,它吐出的所有 JSX 都是组件稳定后应该呈现的内容。

export type ContextItem = {
  name: string,
  color?: string,
  callback: ContextItemCallback,
  keybind?: string,
  checkbox?: () => boolean,
  refs?: MainContextItemRefs,
  setRefs?: (action: MainContextItemRefsAction, ...args: any) => void,
};
export type ContextItemCallback = (e: React.MouseEvent | KeyboardEvent, refs: WindowRefs,
  setRefs: (action: WindowRefsAction, ...args: any) => void) => void; 

export interface Props {
  windowRefs: WindowRefs;
  setWindowRefs: (action: WindowRefsAction, ...args: any) => void
  menuTitle: string;
}

export interface Refs {
  ref: React.MutableRefObject<HTMLDivElement>;
  items: ContextItem[];
  visible: boolean;
  height: number;
  position: V2 | NodePhysics | DSPhysics;
  offset: V2;
}

export const initRefs: Refs = {
  ref: React.createRef() as React.MutableRefObject<HTMLDivElement>,
  items: [],
}

export enum RefsAction {
  SET_ITEMS = "SET_ITEMS",
  SET_REFS = "SET_REFS",
}

export const ContextMenu: React.FC<Props> = ({ windowRefs, setWindowRefs, menuTitle }) => {
  let { state: appState, setState: setAppState, refs: appRefs } = React.useContext<AppContextType>(AppContext); //eslint-disable-line

  let {current: refs } = React.useRef({...windowRefs.ui.menus[menuTitle].refs});

  const [ state, setState ] = React.useState(0);

  const reactRender = () => {
    setState(state + 1);
  }

  const setRefs = (action: RefsAction, ...args: any) => {
    if (action === RefsAction.SET_ITEMS) {
      refs.items = [];
      if (windowRefs.interacts.selectAnchor) {
        refs.items = getNodeContextItems(windowRefs, windowRefs.interacts.selectAnchor);
      }
      reactRender();
    } else if (action === RefsAction.SET_REFS && typeof args[0] === "object") {
      for (let objEnt of Object.entries(args[0])) {
        refs[objEnt[0]] = objEnt[1];
      }
      if ("items" in args[0]) {
        reactRender();
      }
    }
  }

  const itemComps: JSX.Element[] = [];
  for (let i = 0; i < refs.items.length; ++i) {
    itemComps.push(<MainContextItem windowRefs={windowRefs} setWindowRefs={setWindowRefs} mainContextRefs={refs} itemIdx={i} key={i}/>);
  }
  return( //doesnt always return the correct jsx elements
    <div id={menuTitle} className="contextMenu" ref={refs.ref} style={{visibility: "hidden"}}>
      {console.log(itemComps)} // always logs the correct jsx elements
      {itemComps}
    </div>
  );
}

一些重要的注意事项:

  1. 每当refs.items通过SET_ITEMS路径更新时,它都会设置并渲染良好。每当它通过SET_REFS路径更新时,它设置得很好,但没有正确渲染
  2. 当它没有正确渲染时,它会渲染最后一个refs.items数组,所以设置refs.items通过SET_REFS基本上什么都不做。

标签: reactjs

解决方案


推荐阅读