React Native Recompose 操作不触发 reducer
React Native Recompose action not triggering reducer
我正在使用 Recompose 在 React Native 中设置用户登录屏幕,其中包含单独的操作和 reducer 文件,但我的 reducer 从未被调用。目前,只有一个登录按钮会触发 doUserLogin()
重组处理程序:
loginScreen.js
import React from 'react';
import { Button, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { withHandlers, compose } from 'recompose';
import { loginUser } from './user/userActions';
const LoginScreen = ({ user, doUserLogin }) => {
return (
<View style={styles.loginContainer}>
{user ? <Text>Hi, {user.name}!</Text> : <Text>NOT Logged in!</Text>}
<Button title="Log In" onPress={doUserLogin} />
</View>
);
};
export default compose(
connect((state, props) => ({
...state.user,
})),
withHandlers({
doUserLogin: props =>
(event) => {
console.log('LOGIN USER IN HANDLER'); // <-- THIS IS WORKING
loginUser();
},
}),
)(LoginScreen);
doUserLogin()
处理程序依次调用我的操作文件中的 loginUser()
:
userActions.js:
import { LOGIN_REQUEST } from './actionTypes';
export const loginUser = () => {
return (dispatch) => {
console.log('In action'); // <-- THIS IS WORKING
dispatch({ type: LOGIN_REQUEST });
};
};
到目前为止,还不错。但是,当我 dispatch()
时,我的减速器从未被调用。但是 reducer 是 拾取其他动作(从导航等)——它只是没有从上面的 loginUser()
接收动作:
userReducer.js:
import { LOGIN_REQUEST } from './actionTypes';
const userReducer = (state = initialState, action) => {
console.log('In reducer'); <-- ** THIS IS NEVER CALLED **
switch (action.type) {
case LOGIN_REQUEST:
return Object.assign({}, state, {
isFetching: true,
});
case LOGOUT:
return initialState;
default:
return state;
}
};
export default userReducer;
如有任何建议,我们将不胜感激。
好的,看来我能够解决这个问题。简而言之,在 loginScreen.js
中,我需要添加 mapStateToProps
和 mapDispatchToProps
函数,它们将传递给 connect
。 withHandlers
然后可以 dispatch
我的动作文件中的 loginUser()
函数作为道具。
已更新loginScreen.js
import React from 'react';
import { Button, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { withHandlers, compose } from 'recompose';
import { loginUser } from './user/userActions';
const LoginScreen = ({ user, doUserLogin }) => {
return (
<View style={styles.loginContainer}>
{user ? <Text>Hi, {user.name}!</Text> : <Text>NOT Logged in!</Text>}
<Button title="Log In" onPress={doUserLogin} />
</View>
);
};
const mapStateToProps = state => ({
...state.user,
});
const mapDispatchToProps = dispatch => ({
loginUser: () => {
dispatch(loginUser());
},
});
export default compose(
connect(mapStateToProps, mapDispatchToProps),
withHandlers({
doUserLogin: props =>
() => {
console.log('LOGIN USER IN HANDLER');
props.loginUser();
},
}),
)(LoginScreen);
任何额外的 advice/suggestions 仍将不胜感激。
实际上,对于这种特殊情况,您可以完全忽略 withHandlers 助手。
你只需要将 action creator 传递给 react-redux connect 函数,以便将其绑定到 dispatch 函数,就像你展示的那样。更重要的是,请查看 connect 文档。您可以在connect的第三个参数中访问组件的props,并进一步创建依赖于props的处理程序。
你的情况可能是这样的
const mergeProps = (stateProps, dispatchProps, ownProps) => {
return Object.assign({}, ownProps, stateProps, dispatchProps, {
doUserLogin: () => {
console.log('LOGIN USER IN HANDLER');
console.log('accessing a prop from the component', ownProps.user);
dispatchProps.loginUser();
}
});
}
export default connect(mapStateToProps,
mapDispatchToProps,
mergeProps)(LoginScreen);
注意我们如何创建新函数,这些函数将作为组件的新属性提供,类似于 withHandler 助手
我正在使用 Recompose 在 React Native 中设置用户登录屏幕,其中包含单独的操作和 reducer 文件,但我的 reducer 从未被调用。目前,只有一个登录按钮会触发 doUserLogin()
重组处理程序:
loginScreen.js
import React from 'react';
import { Button, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { withHandlers, compose } from 'recompose';
import { loginUser } from './user/userActions';
const LoginScreen = ({ user, doUserLogin }) => {
return (
<View style={styles.loginContainer}>
{user ? <Text>Hi, {user.name}!</Text> : <Text>NOT Logged in!</Text>}
<Button title="Log In" onPress={doUserLogin} />
</View>
);
};
export default compose(
connect((state, props) => ({
...state.user,
})),
withHandlers({
doUserLogin: props =>
(event) => {
console.log('LOGIN USER IN HANDLER'); // <-- THIS IS WORKING
loginUser();
},
}),
)(LoginScreen);
doUserLogin()
处理程序依次调用我的操作文件中的 loginUser()
:
userActions.js:
import { LOGIN_REQUEST } from './actionTypes';
export const loginUser = () => {
return (dispatch) => {
console.log('In action'); // <-- THIS IS WORKING
dispatch({ type: LOGIN_REQUEST });
};
};
到目前为止,还不错。但是,当我 dispatch()
时,我的减速器从未被调用。但是 reducer 是 拾取其他动作(从导航等)——它只是没有从上面的 loginUser()
接收动作:
userReducer.js:
import { LOGIN_REQUEST } from './actionTypes';
const userReducer = (state = initialState, action) => {
console.log('In reducer'); <-- ** THIS IS NEVER CALLED **
switch (action.type) {
case LOGIN_REQUEST:
return Object.assign({}, state, {
isFetching: true,
});
case LOGOUT:
return initialState;
default:
return state;
}
};
export default userReducer;
如有任何建议,我们将不胜感激。
好的,看来我能够解决这个问题。简而言之,在 loginScreen.js
中,我需要添加 mapStateToProps
和 mapDispatchToProps
函数,它们将传递给 connect
。 withHandlers
然后可以 dispatch
我的动作文件中的 loginUser()
函数作为道具。
已更新loginScreen.js
import React from 'react';
import { Button, Text, View } from 'react-native';
import { connect } from 'react-redux';
import { withHandlers, compose } from 'recompose';
import { loginUser } from './user/userActions';
const LoginScreen = ({ user, doUserLogin }) => {
return (
<View style={styles.loginContainer}>
{user ? <Text>Hi, {user.name}!</Text> : <Text>NOT Logged in!</Text>}
<Button title="Log In" onPress={doUserLogin} />
</View>
);
};
const mapStateToProps = state => ({
...state.user,
});
const mapDispatchToProps = dispatch => ({
loginUser: () => {
dispatch(loginUser());
},
});
export default compose(
connect(mapStateToProps, mapDispatchToProps),
withHandlers({
doUserLogin: props =>
() => {
console.log('LOGIN USER IN HANDLER');
props.loginUser();
},
}),
)(LoginScreen);
任何额外的 advice/suggestions 仍将不胜感激。
实际上,对于这种特殊情况,您可以完全忽略 withHandlers 助手。
你只需要将 action creator 传递给 react-redux connect 函数,以便将其绑定到 dispatch 函数,就像你展示的那样。更重要的是,请查看 connect 文档。您可以在connect的第三个参数中访问组件的props,并进一步创建依赖于props的处理程序。
你的情况可能是这样的
const mergeProps = (stateProps, dispatchProps, ownProps) => {
return Object.assign({}, ownProps, stateProps, dispatchProps, {
doUserLogin: () => {
console.log('LOGIN USER IN HANDLER');
console.log('accessing a prop from the component', ownProps.user);
dispatchProps.loginUser();
}
});
}
export default connect(mapStateToProps,
mapDispatchToProps,
mergeProps)(LoginScreen);
注意我们如何创建新函数,这些函数将作为组件的新属性提供,类似于 withHandler 助手