nik*_*sqy 5 javascript render reactjs redux react-hooks
为什么 useSelector 里面的选择器会运行两次?
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>
);
}
Run Code Online (Sandbox Code Playgroud)

这是一个工作片段,显示每次 Child 安装时选择器回调运行两次:
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>
);
}
Run Code Online (Sandbox Code Playgroud)
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
);Run Code Online (Sandbox Code Playgroud)
因为它既在渲染阶段运行,又在分派操作之后运行。因此,第一个日志在<App>渲染时发生,第二个日志在您单击按钮并调度更新存储状态的操作时发生。
useSelector还在安装组件后再次重新运行选择器,以检查是否存在由于构建组件树时分派操作而导致的任何其他更改。
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |