需要帮助~
孩子
const Child = ()=> <div>I'm Child</div
export default Child
Run Code Online (Sandbox Code Playgroud)
家长
const Parent = (props)=> <div>{props.children}</div>
export default React.memo(Parent)
Run Code Online (Sandbox Code Playgroud)
const App = () => {
const [count, setCount] = useState(0)
return(
<div>
<button onClick={()=>setCount(count+1)}></button>
<Parent>
<Child></Child>
</Parent>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
父组件将重新渲染,因此备忘录不起作用,因为它的子组件是一个函数组件
我知道用useMemo解决的方法,但是又丑又不友好,大家有更好的想法吗?
const App = () => {
const [count, setCount] = useState(0)
const children = useMemo(()=><Child></Child>,[])
return(
<div>
<button onClick={()=>setCount(count+1)}></button>
<Parent>
{children}
</Parent>
</div>
)
}
Run Code Online (Sandbox Code Playgroud) 我试图将问题归结为一个尽可能简单的例子:
我们有一个子组件列表,每个子组件都称为NumChoice,每个子组件代表一个数字。NumChoice被包裹在React.memo. 在父组件中,我们有一个布尔数组choices,每个对应一个子组件NumChoice。首先, 的所有元素choices都是false。为了渲染子组件,我们遍历choices,并为每个选择生成相应的子组件NumChoice。我们chooseDivisibles在父组件中定义一个函数,使用useCallback它从每个子组件调用NumChoice。chooseDivisibles获取NumChoice调用它的人的索引并将其对应的元素更改choices为true。每个都是,否则,它的背景颜色是“白色”。NumChoice有一个“红色”的背景色,如果在其对应的元件choicestrue
完整代码可在:https : //codesandbox.io/s/react-rerender-l4e3c?fontsize=14&hidenavigation=1&theme=dark
包装NumChoiceinReact.memo和chooseDivisiblesin useCallback,我们希望只重新渲染NumChoice其相应元素发生choices变化的组件,但 React 会重新渲染它们。chooseDivisibles包含在 中useCallback,除了setChoices. 此外,NumChoice被包裹,React.memo并且只有在指定的道具改变时才应该重新渲染,但它们不会,并且改变choices不应该对重新渲染产生任何影响NumChoice。如果我们排除检查chooseDivisibles前一个和下一个 props的相等性,它会按预期工作,但我认为前一个和下一个的比较chooseDivisibles不应该影响重新渲染, …
我的 bestSellerDummy 数据不会更改,因此我想防止在父级重新呈现时重新呈现相同的产品子级。我尝试在父级中使用 useMemo 并在子级中使用 React.memo 但没有运气,每次父级重新渲染时它仍然显示日志“渲染产品组件..”。我在这里缺少什么?请指教。
注意:每次我在 Product 组件中调用 addToCart 函数(CartContext 的)时,预计都会重新呈现父级。
我正在使用 CartContext,也许与此有关,我不确定。这是沙箱:https://codesandbox.io/s/dazzling-moore-po1c6 ?file=/src/App.js
主页.tsx
const [bestSellerDummy] = useState(
[...new Array(5)].map((item, key) => ({
id: key,
imageUri:'https://1.jpg',
name: 'My Dummy 1',
price: 25,
})),
);
const bestSellers = useMemo(() => {
return bestSellerDummy.map((productDummy, key) => {
return (
<Product key={key} product={productDummy} />
);
});
}, [bestSellerDummy]);
return (
...
{bestSellers}
...
)
Run Code Online (Sandbox Code Playgroud)
产品.tsx
const Product: FunctionComponent<IProductProps> = (
productProps,
) => {
...
console.log('Rendering Product component..');
... …Run Code Online (Sandbox Code Playgroud) 无论React.memo和useMemo钩通过减少重新计算和重新描绘允许性能优化。然而,它们确实有效,因为 React.memo 用于包装函数组件,并且useMemo钩子几乎可以用于任何函数,甚至是纯计算。更重要的useMemo是,通常从父组件React.memo调用子组件,而通常在子组件本身的声明上调用。
虽然两者都有不同的优点,但一个优点React.memo是不必从每个父子关系中调用它。然而,随着钩子的发布,很明显 React 开发希望转向使用钩子来处理状态、副作用事件和其他效果的功能组件。虽然我认为 React 开发团队不会有勇气或无视他们的用户群React.memo在未来 2 年内随时删除,但我想知道他们是否希望最终用户出于风格原因停止使用 React.memo。就像他们有种被动积极地从类组件转移到带有钩子的功能组件。
当使用带有钩子的功能组件时,react 框架是否正在远离React.memo? 如果将来想跟上 React 最佳实践,习惯使用钩子版本会更好吗?
我有一个按钮组件,里面有一个按钮,有一个状态传递给它isActive和一个单击函数。单击按钮时,isActive标志将发生变化,并且根据情况,应用程序将获取一些数据。按钮的父组件不会重新呈现。我搜索了如何强制停止重新渲染组件,发现React.memo(YourComponent)必须完成这项工作,但在我的情况下仍然不起作用。为 memo 函数传递一个检查函数是否重新渲染也是有意义的,我一直将其设置为 false,但我无法向该函数传递另一个参数。帮助。
按钮.tsx
interface Props {
isActive: boolean;
onClick: () => void;
}
const StatsButton: React.FC<Props> = ({ isActive, onClick }) => {
useEffect(() => {
console.log('RERENDER');
}, []);
return (
<S.Button onClick={onClick} isActive={isActive}>
{isActive ? 'Daily stats' : 'All time stats'}
</S.Button>
);
};
export default React.memo(StatsButton);
Run Code Online (Sandbox Code Playgroud)
父级.tsx
const DashboardPage: React.FC = () => {
const {
fetchDailyData,
fetchAllTimeData,
} = useDashboard();
useEffect(() => {
fetchCountry();
fetchAllTimeData();
// eslint-disable-next-line
}, []); …Run Code Online (Sandbox Code Playgroud) react-memo ×5
reactjs ×4
react-hooks ×3
array-map ×1
javascript ×1
memoization ×1
react-native ×1
rerender ×1
use-reducer ×1
usecallback ×1