0

我的提供商下有两个功能组件,

SubApp1并且SubApp2在这里,当我在渲染中增加 counter1 时SubApp1SubApp2即使不需要重新渲染也是如此。

而当我增加 counter2 时SubApp2也在SubApp1渲染。

我知道这确实发生了,但是如何避免这种情况呢?

应用程序.js:

import React, {useContext, useState, memo} from "react";
import "./styles.css";


export const MainContext = React.createContext();

export const MainProvider = ({children})=> {

  const [counter1, setCounter1] = useState(0);
  const [counter2, setCounter2] = useState(0);


  return (
    <MainContext.Provider value={{
      counter1, setCounter1,
      counter2, setCounter2,
    }}>
      {children}
    </MainContext.Provider>
  );
}

export const SubApp1 = memo(()=> {
  const {counter1, setCounter1} = useContext(MainContext);
  console.log('Counter 1: ', counter1);
  return (
    <div className="App">
          <button onClick={()=> {
            setCounter1(counter1+1);
          }}>
            Increase Count 1
          </button>
    </div>
  );
});

export const SubApp2 = memo(()=> {

  const {counter2, setCounter2} = useContext(MainContext);

  console.log('counter2: ', counter2);

  return (
    <div className="App">
          <button onClick={()=> {
            setCounter2(counter2+1);
          }}>
            Increase Count 2
          </button>
    </div>
  );
});


export default function App ({navigation}){


  console.log('App Is rendering...');



  return (
    <div className="App">

         <button onClick={()=> {
            navigation.navigate('SubApp1');
          }}>
            navigate to SubApp1
          </button>

          <button onClick={()=> {
            navigation.navigate('SubApp2');
          }}>
            navigate to SubApp2
          </button>

    </div>
  );
}

index.js:

import React from "react";
import ReactDOM from "react-dom";

import App, {MainProvider} from "./App";

const MainApp = ()=> (
  <MainProvider>
    <App />
  </MainProvider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<MainApp />, rootElement);
4

2 回答 2

2

您应该将计数器作为道具传递给子应用程序。然后 memo 将注意只有带有更改道具的组件才会被重新渲染。

像这样的东西:

export const Wrapper1 = ()=> {
  const {counter1, setCounter1} = useContext(MainContext);
  return (
    <SubApp1 {...{counter1, setCounter1}} />
  );
};

export const SubApp1 = memo(({counter1, setCounter1})=> {

  console.log('Counter 1: ', counter1);
  return (
    <div className="App">
          <button onClick={()=> {
            setCounter1(counter1+1);
          }}>
            Increase Count 1
          </button>
    </div>
  );
});

export const SubApp2 = memo(({counter2, setCounter2})=> {
  console.log('counter2: ', counter2);

  return (
    <div className="App">
          <button onClick={()=> {
            setCounter2(counter2+1);
          }}>
            Increase Count 2
          </button>
    </div>
  );
});


export default function App (){

  const {counter2, setCounter2} = useContext(MainContext);

  console.log('App Is rendering...');

  return (
    <div className="App">
        <Wrapper1/>
        <SubApp2 {...{counter2, setCounter2}} />
    </div>
  );
}

Codesandbox 链接不对...

于 2020-02-16T18:01:13.420 回答
0

我遵循 Peter Ambruzs 的提示,但如果我将 counter1 作为参数传递,我会遇到问题。组件不断重新渲染。

但是,如果我只通过 setCounter1 函数,它就可以正常工作。

下面,我使用打字稿的例子。

const Campaigns = (): JSX.Element => {
  const { setAlert } = useContext(AlertContext);
  return <InnerCampaign {...{ setAlert }} />;
};

const InnerCampaign = memo(
  ({ setAlert }: any): JSX.Element => {...},)

export default Campaigns;

于 2020-03-06T10:55:29.390 回答