使用函数组件时,即createSwitchNavigator上的默认"页面",在导航到底部TabNavigator后,如果状态发生了更改(不仅是条件触发器发生了更改(,整个组件将重新呈现,导致useEffect代码再次执行。
我的导航路线是这样的:
const Routes = createAppContainer(
createSwitchNavigator({
Sign: createSwitchNavigator({
Preload,
SignIn,
}),
App: createBottomTabNavigator(
{
Home,
Employees,
},
),
}),
);
以及在SignIn和Home之间进行导航的功能组件:
const Preload = ({navigation, logged}) => {
useEffect(() => {
if (logged) {
navigation.navigate({routeName: 'Home'});
} else {
navigation.navigate({routeName: 'SignIn'});
}
}, [logged]);
return (
<Container>
<ActivityIndicator color="#1199DD" size={50}/>
</Container>
);
}
还注意到有一个容器/页面连接器,用于使用钩子的流量动作调度器:
const mapDispatchToProps = dispatch => ({
actions: {
...appActions(dispatch),
dispatch
},
})
const mapStateToProps = state => ({
...state.app
})
export default connect(mapStateToProps, mapDispatchToProps)(Preload)
connect函数主要创建一个传递道具、调度和我的商店状态的消费者:
const isFunction = target => typeof target === 'function'
const defaultMapStateToProps = () => ({})
const defaultMapDispatchToProps = () => ({})
export default appContext => (originalMapStateToProps, originalMapDispatchToProps) => {
const { Consumer } = appContext
const mapStateToProps = isFunction(originalMapStateToProps)
? originalMapStateToProps
: defaultMapStateToProps
const mapDispatchToProps = isFunction(originalMapDispatchToProps)
? originalMapDispatchToProps
: defaultMapDispatchToProps
return Component => (props) => (
<Consumer>
{store => (
<Component
{...props}
{...mapStateToProps(store.getState())}
{...mapDispatchToProps(store.dispatch)}
/>
)}
</Consumer>
)
}
我曾尝试使用hook useRef来考虑最后一个值,但由于它重新呈现了所有内容,最后一个数值是不可信的,因为它总是会重新创建这个变量。
真正触发一切重新渲染的是什么?绕过它的最佳方法是什么?
解决方案是放弃启动Consumer的连接/容器,因为我使用React Hooks来发送之前在初始化useReducer
时使用dispatch挂接的操作和状态。
以下示例:
const [useContext, Provider] = createRootContext();
function createRootContext() {
const RootContext = createContext(initialStateCombined);
function useContext() {
const c = React.useContext(RootContext);
if (!c) throw new Error('');
return c;
}
return [useContext, RootContext.Provider];
}
function RootProvider(props) {
const [state, dispatch] = useReducer(appReducer, appInitialState);
const actions = {
app: {...appActions(dispatch)},
};
return <Provider value={{ state, actions }}>{props.children}</Provider>;
}
export { useContext, RootProvider };
这是我的提供者(作为应用程序的最高父级(,我可以通过从状态导入useContext来访问任何内容,如下所示:
const Preload = ({navigation}) => {
const { state: { app } } = useContext();
useEffect(() => {
if (app.logged) {
navigation.navigate('Home');
} else {
navigation.navigate('SignIn');
}
}, [app.logged])
return (
<Container>
<ActivityIndicator color="#1199DD" size={50}/>
</Container>
)
}