- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经通读了有关钩子(Hook)的文档,但没有看到有关使用钩子(Hook)时组件生命周期的足够详细信息,因此我需要您的帮助。
更具体地说,我有一个包含以下相关问题的示例代码:https://github.com/khoitnm/practice-react-redux/tree/main/pro-00-old-react-version/src/comp-04-clickButton
问题 1) 我的功能组件使用了 3 个钩子(Hook):useSelector
, useDispatch
, useEffect
,但是为什么组件执行了 4 次(下面的代码和屏幕截图中有详细信息)?据我理解,应该只有3次:
useSelector
触发这次执行useEffect
触发此执行。 useDispatch
不会触发任何额外的执行,那为什么数据显示4次?下面是我的代码和截图。组件:
let componentCount = 0;
let returnCount = 0;
let useSelectorCount = 0;
let useEffectCount = 0;
const Comp04ClickButtonPage = (): JSX.Element => {
componentCount++;
console.log(`[${componentCount}] component - START ----------------------`);
// useSelector
const stringValueState = useSelector((rootState: RootState): string => {
useSelectorCount++;
console.log(`[${componentCount}] selectorCount: ${useSelectorCount}`);
const result = rootState.comp04ClickButtonSlice.stringValue;
return result;
});
console.log(`[${componentCount}] component - after useSelectorCount`);
// useEffect
const dispatch = useDispatch();
useEffect(() => {
useEffectCount++;
console.log(`[${componentCount}] effectCount: ${useEffectCount}.`);
dispatch(thunkComp04ClickButton(`${new Date().getTime()}`));
}, [dispatch]);
console.log(`[${componentCount}] component - after useEffect`);
const onClickButton = () => {
componentCount = returnCount = useSelectorCount = useEffectCount = 0; // reset counts
console.log(`[${componentCount}] onClickNewValue`);
dispatch(thunkComp04ClickButton(`Random ${new Date().getTime()}`));
};
// render
returnCount++;
return (
<div>
{console.log(`[${componentCount}] renderCount: ${returnCount}`)}
<div>
[{componentCount}], useEffect: {useEffectCount}, useSelectorCount: {useSelectorCount}, returnCount: {returnCount}
</div>
<button onClick={onClickButton}>Click Button</button>
</div>
);
}
砰的一声:
export const thunkComp04ClickButton = (stringValue: string): AppThunk => async (dispatch) => {
try {
console.log(`AppThunk: saveStringValue "${stringValue}" start dispatch`);
dispatch(setComp04ClickButtonState({ stringValue: stringValue }));
console.log(`AppThunk: saveStringValue "${stringValue}" end dispatch`);
} catch (err) {
console.error(`AppThunk: saveStringValue error dispatch` + err, err);
}
};
切片:
type Comp04ClickButtonState = {
stringValue: string;
};
const initialState: Comp04ClickButtonState = {
stringValue: 'Init Comp04ClickButtonState',
};
const comp04ClickButtonSlice = createSlice({
name: 'comp04ClickButtonSlice',
initialState,
reducers: {
setComp04ClickButtonState(state, action: PayloadAction<Comp04ClickButtonState>) {
console.log(`Slice: setComp04ClickButtonState "${action.payload.stringValue}"`);
return action.payload;
},
},
});
export const { setComp04ClickButtonState } = comp04ClickButtonSlice.actions;
export default comp04ClickButtonSlice.reducer;
在screenshot 1 :你会看到 componentCount 是 [4]
和 returnCount: 4
问题2) 当组件被触发时,为什么useSelector
执行多次?
更详细的,我们可以在控制台日志中看到:组件第二次执行时,selectorCount从2次增加到5次(共4次)
[2] selectorCount: 2
[2] component - after useSelectorCount
[2] component - after useEffect
[2] renderCount: 2
[2] selectorCount: 3
[2] effectCount: 1.
AppThunk: saveStringValue "1610983429863" start dispatch
Slice: setComp04ClickButtonState "1610983429863"
[2] selectorCount: 4
AppThunk: saveStringValue "1610983429863" end dispatch
[2] selectorCount: 5
综上所述,当我打开那个网页时,最终的结果是:
更新:正如@lawrence-witt 提到的,<React.StrictMode>
导致对各种事物的双重调用,所以我更改了我的 index.tsx
使用 <React.Fragment>
像这样:
const render = () => {
ReactDOM.render(
<React.Fragment>
<Provider store={store}>
<App />
</Provider>
</React.Fragment>,
document.getElementById('root')
);
};
结果,组件现在只执行了 2 次。但是,正如您在 screenshot 2 中看到的那样,控制台日志仍然显示 useSelector
第一次执行组件时触发4次。因此问题 2 仍然存在:为什么会触发这么多次?
[1] component - START ----------------------
[1] selectorCount: 1
[1] component - after useSelectorCount
[1] component - after useEffect
[1] renderCount: 1
[1] selectorCount: 2
[1] effectCount: 1.
AppThunk: saveStringValue "1611023432655" start dispatch
Slice: setComp04ClickButtonState "1611023432655"
[1] selectorCount: 3
AppThunk: saveStringValue "1611023432655" end dispatch
[1] selectorCount: 4
最佳答案
这里的问题是,当使用 useSelector
Hook 时,它会在每次 Redux 管理的值更改时更新组件。您可以在此处阅读有关 useSelector
的更多信息:https://react-redux.js.org/api/hooks#useselector .
您添加到 useEffect
的依赖项可以删除,因为 dispatch
永远不会改变。 useDispatch
的官方文档可以在这里找到:https://react-redux.js.org/api/hooks#usedispatch .
// This will be called only once when the component is mounted for the first time
useEffect(() => {
initDispatch();
},[]);
const initDispatch = useCallback(()=>{
useEffectCount++;
console.log(`[${componentCount}] effectCount: ${useEffectCount}.`);
dispatch(thunkComp04ClickButton(`${new Date().getTime()}`));
}, [dispatch]);
当 dispatch
被调用时,这段代码仍然会重新渲染组件(因为 dispatch
在 useCallback
依赖数组中)这将强制useSelector
重新渲染组件。
关于reactjs - React函数式组件执行多次,useSelector()在每次函数式组件执行时执行多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65777967/
这是一个Codesandbox . getIDs() 更新 cells,然后 initializeCells() 需要它。但是,此更改不会在调度操作后反射(reflect)出来。尽管如此,我还是可以在
我对 redux/toolkit 很陌生。 我需要使用 redux hook 获取数据 useSelector在我的 react 功能组件中,但数据没有快速准备好,所以看起来 useSelector一
我有一个呈现患者信息的功能组件。在组件中,正在 useEffect 中调度 3 个操作。钩,如下图。每个 Action 都在发出一个异步网络请求。 useEffect(()=>{ di
我需要获取 Redux 存储数据,但并不总是获取每个组件实例化的不同数据。 如何在条件语句中使用 useSelector? 组件应该只在渲染某些子组件时才从 store 获取数据,并且每次都根据子组件
我调用 useSelector从一个组件中成功,该组件从一个 id 派生一个产品名称。 const productId = 25; // whatever const productName = us
最近我一直在阅读react-redux文档https://react-redux.js.org/next/api/hooks还有一个与平等比较和更新相关的部分,内容如下: Call useSelect
嗨,我正在为一个包含 redux 的组件编写单元测试。在测试它时,抛出错误 UseSelector state undefined。 UseSelector 将在收到 api 响应后更新一次。直到它的
页面不渲染,引用 TypeError: state is undefined ,回溯到 中的这一行SelectForm.js : const filter = useSelector(state =>
下面的截图来自 Maximilian Schwarzmüller 的 Udemy 类(class)“React - The Complete Guide (incl Hooks, React Rout
我已经通读了有关钩子(Hook)的文档,但没有看到有关使用钩子(Hook)时组件生命周期的足够详细信息,因此我需要您的帮助。 更具体地说,我有一个包含以下相关问题的示例代码:https://githu
考虑这两个调用 const loading = useSelector((state) => state.example.loading); const { loading } = useSelect
我有一个包含数千行的表格。 import React from "react" import { useSelector } from "react-redux"; import { useEffec
使用 react-devtools 时,它告诉我我的根组件重新渲染的原因是因为钩子(Hook)发生了变化? 当我删除任何 useSelector 时,我的根组件只呈现一次,启用后它会呈现 6 次。 关
我的问题是基于观点而不是基于事实。我想知道什么是更好的做法,我的情况如下:我有一个 react 组件(这是一个父组件),它使用一些 useSelector获取商店数据,它有很多子项。 使用组件数据的最
我正在尝试这样的事情: const useSelector = jest.fn(); jest.mock('react-redux', () => ({ useSelector, })); 然后尝
所以我使用 redux 和 useSelector 钩子(Hook)从商店获取数据。 我可以在一个 reducer 数组中过滤特定的数据,这样组件只在过滤后的数据发生变化时更新,例如: const i
有没有办法在不使用 useSelector 而在 React Component 中使用它来获取状态值 import { superAdmin, zoneManager } from './navig
所以我使用 redux 和 useSelector 钩子(Hook)从商店获取数据。 我可以在一个 reducer 数组中过滤特定的数据,这样组件只在过滤后的数据发生变化时更新,例如: const i
有没有办法在不使用 useSelector 而在 React Component 中使用它来获取状态值 import { superAdmin, zoneManager } from './navig
这是 Refactoring class component to functional component with hooks, getting Uncaught TypeError: func.
我是一名优秀的程序员,十分优秀!