我很不确定如何正确地问这个问题。 (对不起)基本上我想在Saga函数出错时用Error String调用Component中的 onError 函数。所以我可以点燃Snackbar 5秒然后再次隐藏它。
但我不知道我可以从佐贺功能中调用这个函数。目前,它将this.state.error
状态的错误作为字符串返回。我尝试使用componentWillReceiveProps
但是当字符串仍然相同时,这在第二次尝试时不起作用。
为了避免出现问题,我只会发布我所拥有的代码。
我得到了以下组件:
class RegisterForm extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
username: '',
password: '',
SnackbarOpen: false,
};
}
onSubmit = (event) => {
event.preventDefault();
this.props.register(this.state.email, this.state.username, this.state.password);
}
onError(error) {
this.setState({SnackbarOpen: true})
setTimeout(() => {
this.setState({SnackbarOpen: false});
}, 5000);
}
render(): with <form>
}
const mapStateToProps = (state) => ({
error: state.auth.error,
});
const mapDispatchToProps = (dispatch) => ({
register: (email, username, password) => {
dispatch(Actions.register(email, username, password));
}
});
export default connect(mapStateToProps, mapDispatchToProps)(RegisterForm);
这称之为Redux-Saga功能:
import { Types } from './Actions';
import CognitoService from './CognitoService';
function* register(action) {
try {
const result = yield call(CognitoService.register, action);
yield put({ type: Types.registrationSuccess, user: result.user });
} catch(error) {
yield put({ type: Types.registrationFail, error: error.message });
}
}
function* authSaga() {
yield takeLatest(Types.register, register);
}
export default authSaga;
答案 0 :(得分:3)
在auth
缩减器中添加一个开关案例,以匹配操作类型: Types.registrationFail 。然后,它应该提取已注册的错误消息并将其分配给身份验证状态中的auth.error
字段。 e.g。
authReducer(prevState, action){
...
switch(action.type){
case Types.registrationFail:
return {
...prevState,
error: action.error
};
}
...
}
您的组件将通过connect(..)
功能获取商店更改。然后,只需使用componentWillReceiveProps
生命周期方法更新组件,即可检查此消息的值。 e.g。
componentWillReceiveProps(nextProps, nextState){
if(nextProps.error != null && ! nextState.SnackbarOpen){
this.onError();
}
}
在此假设您的快餐栏也在此组件中,并简单地从this.props.error
值中提取其显示文本。否则,可以进一步清理它。
答案 1 :(得分:1)
在这种情况下,我看到两种解决方案。我认为,第一个更倾向于使用redux saga通常的方法。
根据商店值进行渲染
在您的示例中,您可以保存&#34; SnackbarOpen&#34;国家层面的变量。
this.setState({SnackbarOpen: true})
相反,你可以为&#34;注册&#34;组件并在那里保存该变量。所以在这种情况下,saga会在出错时更改商店中的值。简单的例子是:
function* register(action) {
try {
const result = yield call(CognitoService.register, action);
yield put({ type: Types.registrationSuccess, user: result.user });
} catch(error) {
yield put({ type: Types.registrationFail, error: error.message });
yield put({ type: Types.registrationSnackBarOpen });
yield delay(5000);
yield put({ type: Types.registrationSnackBarClose });
}
}
当然,将该值绑定到您的组件。
添加回调
我不建议使用这种方法,但它仍然存在。您只需在操作中添加回调并在传奇中调用它们即可。例如:
组件:
this.props.register(this.state.email, this.state.username, this.state.password, this.onError.bind(this);
佐贺:
function* register(action) {
try {
const result = yield call(CognitoService.register, action);
yield put({ type: Types.registrationSuccess, user: result.user });
} catch(error) {
yield put({ type: Types.registrationFail, error: error.message });
action.onError();
}
}