Javascript 如何避免组件在React中重新启动?

Javascript 如何避免组件在React中重新启动?,javascript,reactjs,redux,Javascript,Reactjs,Redux,使用React和Redux创建一个简单的应用程序 关键是要从服务器获取照片,显示它们,如果您单击照片显示模式窗口,显示更大的照片和评论 应用程序组件的代码 import React, { useEffect } from 'react' import { useSelector, useDispatch } from 'react-redux' import './App.scss' import List from './components/list/List' import Header

使用React和Redux创建一个简单的应用程序

关键是要从服务器获取照片,显示它们,如果您单击照片显示模式窗口,显示更大的照片和评论

应用程序组件的代码

import React, { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import './App.scss'
import List from './components/list/List'
import Header from './components/header/Header'
import Footer from './components/footer/Footer'
import ModalContainer from './containers/ModalContainer'
import { getPhotos, openModal } from './redux/actions/actions'

const App = () => {

  const { isFetching, error } = useSelector(({ photos }) => photos)
  const photos = useSelector(({ photos }) => photos.photos)
  const { isOpen } = useSelector(({ modal }) => modal)
  const dispatch = useDispatch()
  
  useEffect(() => {
    dispatch(getPhotos())
  }, [])

  const getBigPhoto = (id) => {
    dispatch(openModal(id))
  }

  return (
    <div className="container">
      <Header>Test App</Header>
      <div className="list__content">
        {isFetching 
          ? <p>Loading...</p>
          : error 
          ? <p>{error}</p>
          : photos.map(({ id, url }) => (
              <List
                key={id}
                src={url}
                onClick={() => getBigPhoto(id)}
              />
            ))
        }
      </div>
      <Footer>&copy; 2019-2020</Footer>
      {isOpen && <ModalContainer />}
    </div>
  )
} 

export default App
当我点击照片时,我的模态打开,我想停止重新招标所有组件。例如,我使用React.memo.HOC作为标题,如下所示

import React, { memo } from 'react'
import './Header.scss'
import PropTypes from 'prop-types'

const Header = memo(({ children }) => {
  return <div className="header">{children}</div>
})

Header.propTypes = {
  children: PropTypes.string,
}

Header.defaultProps = {
  children: '',
}

export default Header
import React,{memo}来自“React”
导入“./Header.scss”
从“道具类型”导入道具类型
const Header=memo({children})=>{
返回{children}
})
Header.propTypes={
子项:PropTypes.string,
}
Header.defaultProps={
儿童:'',
}
导出默认标题
当我打开和关闭modal时,它可以完美地工作。页眉和页脚不会重新招标。但每次我打开和关闭一个模式窗口时,列表组件都会重新排序。之所以会发生这种情况,是因为每次单击时,列表组件中的prop
onClick={()=>getBigPhoto(id)}
都会创建一个新的匿名函数。正如你们所知道的,若你们的道具改变了,那个么组件将被重新招标


我的问题是,在我的情况下,如何避免列表组件的重新加载?

您可以为接收getBigPhoto和id的列表创建一个容器,使用useCallback创建getBigPhoto,这样函数就不会更改:

const ListContainer = React.memo(function ListContainer({
  id,
  src,
  getBigPhoto,
}) {
  return (
    <List
      key={id}
      src={scr}
      onClick={() => getBigPhoto(id)}
    />
  );
});
const App = () => {
  const { isFetching, error, photos } = useSelector(
    ({ photos }) => photos
  );
  const { isOpen } = useSelector(({ modal }) => modal);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getPhotos());
  }, []);
  //use callback so getBigPhoto doesn't change
  const getBigPhoto = React.useCallback((id) => {
    dispatch(openModal(id));
  }, []);

  return (
    <div className="container">
      <Header>Test App</Header>
      <div className="list__content">
        {isFetching ? (
          <p>Loading...</p>
        ) : error ? (
          <p>{error}</p>
        ) : (
          photos.map(({ id, url }) => (
            // render pure component ListContainer
            <ListContainer
              key={id}
              src={url}
              id={id}
              getBigPhoto={getBigPhoto}
            />
          ))
        )}
      </div>
      <Footer>&copy; 2019-2020</Footer>
      {isOpen && <ModalContainer />}
    </div>
  );
};
const ListContainer=React.memo(函数ListContainer({
身份证件
src,
getBigPhoto,
}) {
返回(
getBigPhoto(id)}
/>
);
});
常量应用=()=>{
常量{isFetching,错误,照片}=useSelector(
({photos})=>照片
);
常量{isOpen}=useSelector(({modal})=>modal);
const dispatch=usedpatch();
useffect(()=>{
发送(getPhotos());
}, []);
//使用回调,使getBigPhoto不会更改
const getBigPhoto=React.useCallback((id)=>{
调度(OpenModel(id));
}, []);
返回(
测试应用程序
{正在抓取吗(
加载

):错误( {错误}

) : ( photos.map({id,url})=>( //呈现纯组件ListContainer )) )} &副本;2019-2020 {isOpen&&} ); };
您可以使用列表组件中的备注作为well@ShubhamVerma,不起作用,因为每次单击onClick prop时都包含一个新函数。在列表中使用'memo'或使用
useCallback
都有两种方法。在备忘录中,您还可以传递条件以比较何时渲染或不渲染。在useCallback中,您可以传递依赖项数组,让react知道何时创建新函数或不创建新函数。
const ListContainer = React.memo(function ListContainer({
  id,
  src,
  getBigPhoto,
}) {
  return (
    <List
      key={id}
      src={scr}
      onClick={() => getBigPhoto(id)}
    />
  );
});
const App = () => {
  const { isFetching, error, photos } = useSelector(
    ({ photos }) => photos
  );
  const { isOpen } = useSelector(({ modal }) => modal);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getPhotos());
  }, []);
  //use callback so getBigPhoto doesn't change
  const getBigPhoto = React.useCallback((id) => {
    dispatch(openModal(id));
  }, []);

  return (
    <div className="container">
      <Header>Test App</Header>
      <div className="list__content">
        {isFetching ? (
          <p>Loading...</p>
        ) : error ? (
          <p>{error}</p>
        ) : (
          photos.map(({ id, url }) => (
            // render pure component ListContainer
            <ListContainer
              key={id}
              src={url}
              id={id}
              getBigPhoto={getBigPhoto}
            />
          ))
        )}
      </div>
      <Footer>&copy; 2019-2020</Footer>
      {isOpen && <ModalContainer />}
    </div>
  );
};