gpt4 book ai didi

javascript - 如何通过重新选择来防止重新渲染?

转载 作者:行者123 更新时间:2023-12-02 21:27:35 25 4
gpt4 key购买 nike

我今天尝试重新选择中间件并防止不必要的重新渲染。

这是我的reducer.js:

const INITIAL_STATE = {
dogs: 100,
cats: 12312302384
};

const pets = (state = INITIAL_STATE, action) => {
switch (action.type) {
case "CHANGE_DOGS":
return {
...state, dogs: state.dogs + 1
};
case "CHANGE_CATS":
return {
...state, cats: state.cats + 1
};
default:
return { ...state };
}
};

export default pets;

这是我的 main.js:

import React from "react";
import { createSelector } from "reselect";
import { useSelector, useDispatch } from "react-redux";

function ReduxDeneme(props) {
// Selectors - Classic style - NON Memoized!
// const dogsData = useSelector(state => state.pets.dogs);
// const catsData = useSelector(state => state.pets.cats);

// Dogs rendering.. --> First opening..
// 10:11:28.070 index.js:18 CATS rendering.. --> First opening..
// 10:11:29.703 index.js:13 Dogs rendering.. --> Press "ChangeDogs" button.
// 10:11:29.703 index.js:18 CATS rendering.. --> Press "ChangeDogs" button.
// 10:11:33.143 index.js:13 Dogs rendering.. --> Press "ChangeCats" button.
// 10:11:33.143 index.js:18 CATS rendering.. --> Press "ChangeCats" button.

// Selectors - Memoized version RESELECT middleware'i ile..
const dogsDataMemo = createSelector(
state => state.pets.dogs,
dogs => dogs
);
const catsDataMemo = createSelector(
state => state.pets.cats,
cats => cats
);

const dogsData = useSelector(dogsDataMemo)
const catsData = useSelector(catsDataMemo)


// Components
const Dogs = ({ dogsData }) => {
console.log("Dogs rendering..");
return <h1>{dogsData}</h1>;
};

const Cats = ({ catsData }) => {
console.log("Cats rendering..");
return <h1>{catsData}</h1>;
};

// Actions

const dispatch = useDispatch();
const changeDogs = () => dispatch({ type: "CHANGE_DOGS" });
const changeCats = () => dispatch({ type: "CHANGE_CATS" });

return (
<div>
<Dogs dogsData={dogsData} />
<Cats catsData={catsData} />
<button onClick={changeDogs}>Change Dogs</button>
<button onClick={changeCats}>Change CATS</button>
</div>
);
}

export default ReduxDeneme;
  • 1.场景:我使用了经典的非内存样式选择器。控制台有6次console.log。 (第一次打开时2次-这是正常的-,点击“换狗”按钮时2次,点击“换猫”按钮时2次)。这意味着发生了 6 次重新渲染。
  • 2.场景:我使用了reselect中间件来防止不必要的重新渲染。但是,它不起作用,或者我误解了重新选择的含义。

有人可以解释一下正确的方法或者我哪里做错了吗?

最佳答案

您正在组件内定义选择器。您应该在室外进行(例如,靠近 reducer 的某个地方)。

目前,您正在每次渲染后重新创建选择器。这是一个更好的方法:

// inside reducer.js

export const petsSel = state => state.pets;
export const dogsDataMemo = createSelector(
petsSel,
pets => pets.dogs
);
export const catsDataMemo = createSelector(
petsSel,
pets => pets.cats
);

添加了一个codesandbox,其中包含基于您的代码的工作示例:https://codesandbox.io/s/delicate-snowflake-5ssrw

要实现您想要的效果,您还需要使用 React.memo ( https://reactjs.org/docs/react-api.html#reactmemo ):

const Dogs = React.memo(({ dogsData }) => {
console.log("Dogs rendering..");
return <h1>{dogsData}</h1>;
});

关于javascript - 如何通过重新选择来防止重新渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60702071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com