为啥useSelector里面的选择器会运行两次?
Posted
技术标签:
【中文标题】为啥useSelector里面的选择器会运行两次?【英文标题】:Why does the selector inside useSelector run twice?为什么useSelector里面的选择器会运行两次? 【发布时间】:2021-04-25 21:29:17 【问题描述】:为什么useSelector里面的选择器会运行两次?
Example
const selector = (state) =>
console.log("invoke Selector");
return state;
;
function App()
console.log("render App");
const count = useSelector(selector);
const dispatch = useDispatch();
return (
<div className="App">
<button onClick=() => dispatch( type: "INCREMENT" )>Increment</button>
<button onClick=() => dispatch( type: "DECREMENT" )>Decrement</button>
<p>count</p>
</div>
);
这是一个有效的 sn-p,显示每次 Child 挂载时选择器回调运行两次:
const Provider, useDispatch, useSelector = ReactRedux;
const createStore, applyMiddleware, compose = Redux;
function count(state, action)
console.log('reducing action:',action.type)
switch (action.type)
case "INCREMENT":
return ...state,count:state.count+1;
case "DECREMENT":
return ...state,count:state.count-1;
default:
return state;
const store = createStore(count,count:0);
const selector = (state) =>
console.log("invoke Selector",state);
return state.count;
;
function Child()
console.log("render Child");
const count = useSelector(selector);
const dispatch = useDispatch();
return (
<div className="App">
<button onClick=() => dispatch( type: "INCREMENT" )>Increment</button>
<button onClick=() => dispatch( type: "DECREMENT" )>Decrement</button>
<p>count</p>
</div>
);
const App = () =>
const [show,setShow] = React.useState(true);
return (<div>
<button onClick=()=>setShow(s=>!s)>toggle child</button>
show?<Child />:'none'
</div>)
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store=store>
<App />
</Provider>,
rootElement
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>
【问题讨论】:
如果使用得当,这应该不是问题。您是出于好奇而询问,还是您有与此行为相关的实际问题? (XY问题) @idmean 出于好奇。 【参考方案1】:因为它在渲染阶段和调度操作之后都运行。因此,第一个日志发生在 <App>
呈现时,第二个日志发生在您单击按钮并调度更新存储状态的操作时。
useSelector
还会在组件挂载后第二次重新运行选择器,以检查是否由于在构建组件树时调度了动作而导致任何其他更改。
【讨论】:
不知道为什么第一次加载app,selector也跑了两次。 因为React double-renders components in<StrictMode>
.
但毕竟渲染的时候,对控制台有双重显示
我还删除了示例中的 useSelector
在挂载后运行第二次检查。以上是关于为啥useSelector里面的选择器会运行两次?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 jQuery UI 的日期选择器会与动态 DOM 发生冲突?
当我第二次设置它的 ItemsSource 时,为啥这个选择器会崩溃?