Ответ 1
const enhance = compose(
withRouter,
withStyles(styles, 'some style'),
connect(mapStateToProps, mapDispatchToProps),
....
export default enhance(MyComponent);
Я начинаю разрабатывать веб-приложение с использованием React JS. Я купил тему из тематического леса. В теме они используют компоновку, подобную этой в компоненте.
...Other code here
Login.propTypes = {
classes: PropTypes.shape({}).isRequired,
width: PropTypes.string.isRequired
};
export default compose(withWidth(), withStyles(themeStyles, { withTheme: true }))(Login);
Как вы можете видеть, их код использует compose в конце при экспорте Component. Я не могу изменить их встроенную структуру. То, что мне нравится делать сейчас, я тоже люблю использовать функцию соединения.
Обычно соединение используется в месте компоновки. Теперь, если я хочу использовать соединение для работы с состоянием приложения, как я могу использовать его вместе с compose?
const enhance = compose(
withRouter,
withStyles(styles, 'some style'),
connect(mapStateToProps, mapDispatchToProps),
....
export default enhance(MyComponent);
import {bindActionCreators} from 'redux';
import compose from 'recompose/compose';
import { connect } from 'react-redux';
...Other code here
function mapStateToProps(state) {
return {
//return state
}
}
function mapDispatchToProps(){
return bindActionCreators({
//actions
}, dispatch);
}
Login.propTypes = {
classes: PropTypes.shape({}).isRequired,
width: PropTypes.string.isRequired
};
export default compose(withWidth(), withStyles(styles, {withTheme: true}), connect(mapStateToProps, mapDispatchToProps))(Login);
Надеюсь, это решит вашу проблему.
compose
не избавляется от шаблона передачи функции в результате вызова функции, но сокращает ее использование до единицы.
Только один HOC, никакой выгоды от использования compose:
// withStyles, without compose
export default withStyles(styles)(MyComponent)
// withStyles, with compose
export default compose(withStyles(styles))(MyComponent)
// connect, without compose
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
// connect, with compose
export default compose(connect(mapStateToProps, mapDispatchToProps))(MyComponent)
Обратите внимание, что запуск другого вызова функции сразу после вызова функции, который только недавно вошел в моду, все еще существует в compose
.
С двумя HOC есть преимущество от compose
потому что вложенность parens меньше:
// two HOCs, without compose
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(MyComponent))
// two HOCs, with compose
export default compose(connect(mapStateToProps, mapDispatchToProps), withStyles(styles))(MyComponent)
Это все еще может быть трудно понять, если вы не привыкли к безымянной функции, вызываемой сразу после ее создания. Если вы предпочитаете, вы можете дать ему имя:
// two HOCs, with compose
const enhance = compose(connect(mapStateToProps, mapDispatchToProps, withStyles(styles));
// export default enhance(MyComponent);
Я предпочитаю использовать compose, когда имеется более одного HOC, и использовать его напрямую. Я думаю, что сокращение вложения полезно, но давать ему общее имя, например, enhance
не нужно.
import {connect} from "react-redux";
import {compose} from 'redux'
class BookList extends Component {
componentDidMount() {
const {bookstoreService} = this.props;
const data = bookstoreService.getBooks();
this.props.booksLoaded(data);
}
render() {
const {books} = this.props;
return (
<ul>
{books.map(book => {
return (
<li key={book.id}>
<BookListItem book={book}/>
</li>
);
})}
</ul>
);
}
}
const mapStateToProps = ({books}) => {
return {books};
};
const mapDispatchToProps = dispatch => {
return {
booksLoaded: newBooks => {
dispatch(booksLoaded(newBooks));
}
};
};
export default compose(withBookstoreService(), connect(mapStateToProps, mapDispatchToProps))(BookList);