Javascript 如何避免组件在React中重新启动?
使用React和Redux创建一个简单的应用程序 关键是要从服务器获取照片,显示它们,如果您单击照片显示模式窗口,显示更大的照片和评论 应用程序组件的代码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
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>© 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时,它可以完美地工作。页眉和页脚不会重新招标。但每次我打开和关闭一个模式窗口时,列表组件都会重新排序。之所以会发生这种情况,是因为每次单击时,列表组件中的proponClick={()=>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>© 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>© 2019-2020</Footer>
{isOpen && <ModalContainer />}
</div>
);
};