有没有办法使只设置上下文的组件在上下文更新时不重新呈现?反应

时间:2019-12-16 15:57:58

标签: javascript reactjs react-hooks

我有上下文,然后有一个设置该上下文的组件,但随后不必要地重新调用其中的所有内容。

代码如下:

export const SelectedContentContext = createContext();
export const SelectedContentProvider = ({ children }) => {
  const [selectedContent, setSelectedContent] = useState(0);

  return (
    <SelectedContentContext.Provider
      value={{ selectedContent, setSelectedContent }}
    >
      {children}
    </SelectedContentContext.Provider>
  );
};

export const useSelectedContentValue = () => useContext(SelectedContentContext);

然后,将其导入到要设置如下的组件中:

import { useSelectedContentValue } from "../context";
...
const { setSelectedContent } = useSelectedContentValue();

并这样设置:

setSelectedContent(c => c - 1)

但是还有很多代码,包括EventListeners,由于组件使用Context,因此不必重新运行,但仍然可以重新运行。

所以我要问的是是否有某种方法可以使它不重新渲染。就像以某种方式将其放入单独的组件或自定义挂钩中一样,或者通过Context中的setState()使其结合起来,就无法解决。


编辑:更好地表示其外观。

export const Component = () => {
    const [node, setNode] = useState();

    return (
    <>
      <section ref={ref => setNode(ref)}><section/>
      {node ? <Component2 prop={node}/> : null}
    </>
    );
}

我设置了setSelectedContent();的组件。

import { useSelectedContentValue } from "../context";

export const Component2 = (props) => {
    let ref = props.prop;

    const { setSelectedContent } = useSelectedValue();

    useEffect(() => {
        ...
        const handleEnd = (e) => {
          ...
          if(...){
              setSelectedContent(c => c + 1);
          }
        }

    ref.addEventListener("touchend", handleEnd);

    return () => {
      ref.removeEventListener("touchend", handleEnd);
    };

    },[ref, setSelectedContent]);

    return null;
}

使用useEffect进行返回清除,因为我知道setSelectedContent将导致重新渲染,因此我必须将removeEventListener删除

1 个答案:

答案 0 :(得分:0)

我会

export const Component = () => {
    const node = useRef();

    return (
    <>
      <section ref={node}><section/>
      {node ? <Component2 node={node}/> : null}
    </>
    );
}

然后

import { useSelectedContentValue } from "../context";

export const Component2 = ({ node }) => {
    const { setSelectedContent } = useSelectedValue();

    useEffect(() => {
        ...
        const handleEnd = (e) => {
          ...
          if(...){
              setSelectedContent(c => c + 1);
          }
        }

    node.current.addEventListener("touchend", handleEnd);

    return () => {
      node.current.removeEventListener("touchend", handleEnd);
    };

    },[]);

    return null;
}