使用Redux时如何防止页面不必要的渲染?



当我运行代码时,首先呈现的是Main页面和Component_A页面。然后,当我按下按钮并增加或减少计数时,只有页面A呈现。B页不呈现。但是当我转到Component_B页面时,当我按下那里的按钮时,Component_A和Component_B页面都会呈现。如何只呈现我正在使用的页面?

Main.js

import React from 'react';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reducer from './context/reducer';
import initialState from './context/store';
import {Component_A, Componenet_B} from './components';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
const store = createStore(reducer, initialState);
const Stack = createStackNavigator();
const Main = () => {
console.log('renderMain');
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="A" component={Component_A} />
<Stack.Screen name="B" component={Componenet_B} />
</Stack.Navigator>
</NavigationContainer>
</Provider>
);
};
export default Main;

Component_A.js

import React from 'react';
import {Button, Text, View} from 'react-native';
import {useSelector, useDispatch} from 'react-redux';
const Component_A = ({navigation}) => {
const dispatch = useDispatch();
const myCounter = useSelector((state) => state.counter);
console.log('renderA');
return (
<View style={{backgroundColor: '#eceff1', flex: 1}}>
<Text>Component_A</Text>
<Text style={{fontSize: 50}}>Counter:{myCounter}</Text>
<Button title="Go to B" onPress={() => navigation.navigate('B')} />
<Button title="Increase" onPress={() => dispatch({type: 'Increase'})} />
<Button title="Decrease" onPress={() => dispatch({type: 'Decrease'})} />
</View>
);
};
export default Component_A;

Component_B.js

import React from 'react';
import {Text, View, Button} from 'react-native';
import {useSelector, useDispatch} from 'react-redux';
const Componenet_B = ({navigation}) => {
const {counter} = useSelector((state) => state);
const dispatch = useDispatch();
console.log('renderB');
return (
<View style={{backgroundColor: '#bdbdbd', flex: 1}}>
<Text>Componenet_B</Text>
<Text style={{fontSize: 50}}>{counter}</Text>
<Button title="Go to A" onPress={() => navigation.navigate('A')} />
<Button title="Increase" onPress={() => dispatch({type: 'Increase'})} />
<Button title="Decrease" onPress={() => dispatch({type: 'Decrease'})} />
</View>
);
};
export default Componenet_B;

reducer.js

function reducer(state, action) {
switch (action.type) {
case 'Increase':
state.counter = state.counter + 1;
return {...state};
case 'Decrease':
state.counter = state.counter - 1;
return {...state};
default:
return state;
}
}
export default reducer;

store.js

const initialState = {
counter: 0,
};
export default initialState;
enter code here

感谢您的帮助

即使你的reducer可以工作,我也会坚持不可变的更新模式

function reducer(state, action) {
switch (action.type) {
case 'Increase':
return { ...state, counter: state.couner + 1 };
case 'Decrease':
return { ...state, counter: state.counter - 1 };
default:
return state;
}
}

如果你做const counter = useSelector((state) => state.counter);,那么组件只会在计数器改变时渲染。但是,不是传递一个匿名箭头函数给useSelector,而是使用重选选择器函数,这样组件A和B都可以重用相同的选择器函数。

最新更新