在 redux 中使用重组
use recompose in redux
我有一个使用 react 和 redux 开发的组件。现在我想使用重组,我不明白将它与 redux 一起使用的有组织的方式。通过有条理的方式,我的意思是说之前我曾经有两个函数,如 mapStateToProps
和 mapDispatchToProps
,它们被包装在 connect HOC
中,在我看来这使代码看起来更具可读性和清晰度。我的问题是我如何像我为 redux 部分所做的那样做同样的事情?我在搜索那种方式时找不到,所以我不确定是否有办法,是否有人可以通过分享来帮助我,好吗?
这是我的代码
import React from 'react';
import { connect } from 'react-redux';
const mapStateToProps = state => ({
loginData: state.loginData,
});
const mapDispatchToProps = dispatch => ({
login: user => dispatch(login(user)),
});
class Login extends React.Component<{ login: Function }> {
state = {
error: false,
user: {
email: '',
password: '',
},
};
handleChange = (e) => {
const { name, value } = e.target;
this.setState({ user: { ...this.state.user, [name]: value } });
};
handleSubmit = (e) => {
e.preventDefault();
this.props.login(this.state.user);
};
renderError() {
if (this.state.error) {
return (
<ErrorMessage>
The following email is not associated with us. Please create an
account to use our service
</ErrorMessage>
);
}
return <div />;
}
render() {
const { user } = this.state;
return (
<WhitePart>
<UpperPart>
<TitleContainer>
<TitleText>Login</TitleText>
</TitleContainer>
{this.renderError()}
<Form>
<form onSubmit={this.handleSubmit}>
<StyledField
label="Email"
id="email"
name="email"
type="text"
value={user.email}
placeholder="Email"
className="input-field"
component={GTextField}
onChange={this.handleChange}
style={{
marginBottom: '20px',
}}
required
fullWidth
/>
<StyledField
label="Password"
id="password"
name="password"
type="password"
value={user.password}
placeholder="Password"
className="input-field"
component={GPasswordField}
onChange={this.handleChange}
required
fullWidth
/>
<ButtonContainer>
<PrimaryButton
type="submit"
style={{
textTransform: 'none',
fontFamily: 'Lato',
fontWeight: 300,
}}
>
Login
</PrimaryButton>
</ButtonContainer>
</form>
</Form>
</UpperPart>
</WhitePart>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Login);
对于 handleChange 和 handleSubmit 我可以使用 withHandler 和 withState 但对于 mapStateToProps 和 mapDispatchToProps 我不熟悉。
对于 mapStateToProps:
您可以使用 reselect 将选择器逻辑移动到另一个文件中,然后跨组件共享选择器。
对于 mapDispatchToProps:
您可以使用 redux-thunk or redux-saga 将异步逻辑移动到单独的文件中。
直接回答你的问题:
export default compose(
connect(
mapStateToProps,
mapDispatchToProps
),
withStateHandlers,
withHandler,
)(Login);
奖金!
使用 recompose
时不需要单独的 mapDispatchToProps
。
我们喜欢对所有处理程序使用 Recompose 的 withHandlers
,包括 Redux 调度。
看起来像这样。
import React from 'react';
import { connect } from 'react-redux';
import { signUpUser, loginUser } from './someActionsFile';
const LandingScreen = props => (
<ButtonContainer>
<Button title="Sign Up" onPress={props.dispatchSignUpUser} />
<Button title="Log In" onPress={props.dispatchLoginUser} />
<Button title="Say Hi!!" onPress={props.sayHi} />
</ButtonContainer>
);
const mapStateToProps = state => ({
loginData: state.loginData,
});
const myHandlers = withHandlers({
dispatchSignUpUser: ({ dispatch }) => () => {
dispatch(signUpUser());
},
dispatchLoginUser: ({ dispatch }) => () => {
dispatch(loginUser());
},
sayHi: () => () => {
console.log('Hi!!');
}
});
export default compose(
connect(mapStateToProps), // Once connect() is composed `dispatch` is prop.
myHandlers
)(LandingScreen);
我有一个使用 react 和 redux 开发的组件。现在我想使用重组,我不明白将它与 redux 一起使用的有组织的方式。通过有条理的方式,我的意思是说之前我曾经有两个函数,如 mapStateToProps
和 mapDispatchToProps
,它们被包装在 connect HOC
中,在我看来这使代码看起来更具可读性和清晰度。我的问题是我如何像我为 redux 部分所做的那样做同样的事情?我在搜索那种方式时找不到,所以我不确定是否有办法,是否有人可以通过分享来帮助我,好吗?
这是我的代码
import React from 'react';
import { connect } from 'react-redux';
const mapStateToProps = state => ({
loginData: state.loginData,
});
const mapDispatchToProps = dispatch => ({
login: user => dispatch(login(user)),
});
class Login extends React.Component<{ login: Function }> {
state = {
error: false,
user: {
email: '',
password: '',
},
};
handleChange = (e) => {
const { name, value } = e.target;
this.setState({ user: { ...this.state.user, [name]: value } });
};
handleSubmit = (e) => {
e.preventDefault();
this.props.login(this.state.user);
};
renderError() {
if (this.state.error) {
return (
<ErrorMessage>
The following email is not associated with us. Please create an
account to use our service
</ErrorMessage>
);
}
return <div />;
}
render() {
const { user } = this.state;
return (
<WhitePart>
<UpperPart>
<TitleContainer>
<TitleText>Login</TitleText>
</TitleContainer>
{this.renderError()}
<Form>
<form onSubmit={this.handleSubmit}>
<StyledField
label="Email"
id="email"
name="email"
type="text"
value={user.email}
placeholder="Email"
className="input-field"
component={GTextField}
onChange={this.handleChange}
style={{
marginBottom: '20px',
}}
required
fullWidth
/>
<StyledField
label="Password"
id="password"
name="password"
type="password"
value={user.password}
placeholder="Password"
className="input-field"
component={GPasswordField}
onChange={this.handleChange}
required
fullWidth
/>
<ButtonContainer>
<PrimaryButton
type="submit"
style={{
textTransform: 'none',
fontFamily: 'Lato',
fontWeight: 300,
}}
>
Login
</PrimaryButton>
</ButtonContainer>
</form>
</Form>
</UpperPart>
</WhitePart>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Login);
对于 handleChange 和 handleSubmit 我可以使用 withHandler 和 withState 但对于 mapStateToProps 和 mapDispatchToProps 我不熟悉。
对于 mapStateToProps:
您可以使用 reselect 将选择器逻辑移动到另一个文件中,然后跨组件共享选择器。
对于 mapDispatchToProps:
您可以使用 redux-thunk or redux-saga 将异步逻辑移动到单独的文件中。
直接回答你的问题:
export default compose(
connect(
mapStateToProps,
mapDispatchToProps
),
withStateHandlers,
withHandler,
)(Login);
奖金!
使用 recompose
时不需要单独的 mapDispatchToProps
。
我们喜欢对所有处理程序使用 Recompose 的 withHandlers
,包括 Redux 调度。
看起来像这样。
import React from 'react';
import { connect } from 'react-redux';
import { signUpUser, loginUser } from './someActionsFile';
const LandingScreen = props => (
<ButtonContainer>
<Button title="Sign Up" onPress={props.dispatchSignUpUser} />
<Button title="Log In" onPress={props.dispatchLoginUser} />
<Button title="Say Hi!!" onPress={props.sayHi} />
</ButtonContainer>
);
const mapStateToProps = state => ({
loginData: state.loginData,
});
const myHandlers = withHandlers({
dispatchSignUpUser: ({ dispatch }) => () => {
dispatch(signUpUser());
},
dispatchLoginUser: ({ dispatch }) => () => {
dispatch(loginUser());
},
sayHi: () => () => {
console.log('Hi!!');
}
});
export default compose(
connect(mapStateToProps), // Once connect() is composed `dispatch` is prop.
myHandlers
)(LandingScreen);