与 useSelector 混淆
Getting confused with useSelector
所以我想使用 react-redux
中的 connect
函数访问状态(使用 redux 进行状态管理)。
connect(mapStateToProps)(MyComponent)
但是当我尝试访问状态值时,它返回未定义。
然后,我所做的唯一更改是删除 connect
并使用 useSelector
挂钩引入我的组件并且它工作正常。
直到现在,我一直认为它们是相同的(在提供对状态的访问方面),但它的工作方式完全不同。
这是代码(我认为在这个问题的上下文中没有用,但也许我错了);
使用useSelector
const UnRegisteredStack = (props) => {
const { token, verified } = useSelector((state) => ({
token: state.token,
verified: state.verified,
}));
return (
<NavigationContainer>
{token == null ? (
<unRegistered.Navigator
initialRouteName="login"
screenOptions={{ headerShown: false }}
>
<unRegistered.Screen name="login" component={Login} />
<unRegistered.Screen name="register" component={Register} />
<unRegistered.Screen name="passwordreset" component={PasswordReset} />
</unRegistered.Navigator>
) : (
<unRegistered.Navigator
initialRouteName="verifyemail"
screenOptions={{ headerShown: false }}
>
{verified == null ? (
<unRegistered.Screen name="verifyemail" component={VerifyEmail} />
) : (
<unRegistered.Screen name="details" component={Details} />
)}
</unRegistered.Navigator>
)}
</NavigationContainer>
);
};
使用connect
const UnRegisteredStack = (props) => {
const { token, verified } = props;
return (
<NavigationContainer>
{token == null ? (
<unRegistered.Navigator
initialRouteName="login"
screenOptions={{ headerShown: false }}
>
<unRegistered.Screen name="login" component={Login} />
<unRegistered.Screen name="register" component={Register} />
<unRegistered.Screen name="passwordreset" component={PasswordReset} />
</unRegistered.Navigator>
) : (
<unRegistered.Navigator
initialRouteName="verifyemail"
screenOptions={{ headerShown: false }}
>
{verified == null ? (
<unRegistered.Screen name="verifyemail" component={VerifyEmail} />
) : (
<unRegistered.Screen name="details" component={Details} />
)}
</unRegistered.Navigator>
)}
</NavigationContainer>
);
};
const mapStateToProps = (state) => ({
token: state.token,
verified: state.verified
})
connect(mapStateToProps)(UnRegisteredStack)
文档中省略的一个区别是,使用 useSelector
的组件使用更新的 React 钩子哲学,然后可以在不需要单独的包装器组件的情况下自行使用,而 connect(...)(UnRegisteredStack)
是使用较旧的通过将组件包装在包装器中来增加组件的哲学,例如:
const UnRegisteredStackHooks = (props) => {
const { token, verified } = useSelector((state) => ({
token: state.token,
verified: state.verified,
}));
// rest of component
}
const UnRegisteredStackUnconnected = (props) => {
// rest of component
}
const UnRegisteredStackConnected = connect(mapStateToProps)(UnRegisteredStackUnconnected);
const App = () => (
<Provider store={store}>
{/* Works ok */}
<UnRegisteredStackHooks />
{/* Needs the props passed */}
<UnRegisteredStackUnconnected token={store.getState().token} />
{/* Works ok */}
<UnRegisteredStackConnected />
</Provider>
);
这两种方法各有利弊。使用 connect
,您可以保留一个组件的选项,该组件无需与 redux 耦合即可工作,因为您始终可以在没有 connect
的情况下导出组件并在其他地方引入连接。如果您不想创建模拟商店,这在测试时特别有用。
另一方面,hooks 使定义组件变得更加简单,如果需要测试,您可以随时模拟 hooks。
所以我想使用 react-redux
中的 connect
函数访问状态(使用 redux 进行状态管理)。
connect(mapStateToProps)(MyComponent)
但是当我尝试访问状态值时,它返回未定义。
然后,我所做的唯一更改是删除 connect
并使用 useSelector
挂钩引入我的组件并且它工作正常。
直到现在,我一直认为它们是相同的(在提供对状态的访问方面),但它的工作方式完全不同。
这是代码(我认为在这个问题的上下文中没有用,但也许我错了);
使用useSelector
const UnRegisteredStack = (props) => {
const { token, verified } = useSelector((state) => ({
token: state.token,
verified: state.verified,
}));
return (
<NavigationContainer>
{token == null ? (
<unRegistered.Navigator
initialRouteName="login"
screenOptions={{ headerShown: false }}
>
<unRegistered.Screen name="login" component={Login} />
<unRegistered.Screen name="register" component={Register} />
<unRegistered.Screen name="passwordreset" component={PasswordReset} />
</unRegistered.Navigator>
) : (
<unRegistered.Navigator
initialRouteName="verifyemail"
screenOptions={{ headerShown: false }}
>
{verified == null ? (
<unRegistered.Screen name="verifyemail" component={VerifyEmail} />
) : (
<unRegistered.Screen name="details" component={Details} />
)}
</unRegistered.Navigator>
)}
</NavigationContainer>
);
};
使用connect
const UnRegisteredStack = (props) => {
const { token, verified } = props;
return (
<NavigationContainer>
{token == null ? (
<unRegistered.Navigator
initialRouteName="login"
screenOptions={{ headerShown: false }}
>
<unRegistered.Screen name="login" component={Login} />
<unRegistered.Screen name="register" component={Register} />
<unRegistered.Screen name="passwordreset" component={PasswordReset} />
</unRegistered.Navigator>
) : (
<unRegistered.Navigator
initialRouteName="verifyemail"
screenOptions={{ headerShown: false }}
>
{verified == null ? (
<unRegistered.Screen name="verifyemail" component={VerifyEmail} />
) : (
<unRegistered.Screen name="details" component={Details} />
)}
</unRegistered.Navigator>
)}
</NavigationContainer>
);
};
const mapStateToProps = (state) => ({
token: state.token,
verified: state.verified
})
connect(mapStateToProps)(UnRegisteredStack)
文档中省略的一个区别是,使用 useSelector
的组件使用更新的 React 钩子哲学,然后可以在不需要单独的包装器组件的情况下自行使用,而 connect(...)(UnRegisteredStack)
是使用较旧的通过将组件包装在包装器中来增加组件的哲学,例如:
const UnRegisteredStackHooks = (props) => {
const { token, verified } = useSelector((state) => ({
token: state.token,
verified: state.verified,
}));
// rest of component
}
const UnRegisteredStackUnconnected = (props) => {
// rest of component
}
const UnRegisteredStackConnected = connect(mapStateToProps)(UnRegisteredStackUnconnected);
const App = () => (
<Provider store={store}>
{/* Works ok */}
<UnRegisteredStackHooks />
{/* Needs the props passed */}
<UnRegisteredStackUnconnected token={store.getState().token} />
{/* Works ok */}
<UnRegisteredStackConnected />
</Provider>
);
这两种方法各有利弊。使用 connect
,您可以保留一个组件的选项,该组件无需与 redux 耦合即可工作,因为您始终可以在没有 connect
的情况下导出组件并在其他地方引入连接。如果您不想创建模拟商店,这在测试时特别有用。
另一方面,hooks 使定义组件变得更加简单,如果需要测试,您可以随时模拟 hooks。