正如here所示,我试图尽可能多地将我的应用程序组件分离,并让他们不知道任何存储或动作创建者。
目标是让他们管理自己的状态并调用函数来发出更改。我被告知你使用道具这样做。
考虑
// Menu.jsx
import React from 'react'
import { className } from './menu.scss'
import Search from 'components/search'
class Menu extends React.Component {
render () {
return (
<div className={className}>
<a href='#/'>Home</a>
<a href='#/foo'>foo</a>
<a href='#/bar'>bar</a>
<Search />
</div>
)
}
}
和
// Search.jsx
import React from 'react'
import { className } from './search.scss'
class Search extends React.Component {
render () {
let { searchTerm, onSearch } = this.props
return (
<div className={`search ${className}`}>
<p>{searchTerm}</p>
<input
type='search'
onChange={(e) => onSearch(e.target.value)}
value={searchTerm}
/>
</div>
)
}
}
Search.propTypes = {
searchTerm: React.PropTypes.string,
onSearch: React.PropTypes.function
}
export default Search
阅读here我看到Provider
和connect
的智能使用,我的实现看起来像这样:
import { bindActionCreators, connect } from 'redux'
import actions from 'actions'
function mapStateToProps (state) {
return {
searchTerm: state.searchTerm
}
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({
dispatchSearchAction: actions.search
}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(Search)
假设我有一个商店处理searchTerm
作为全球状态的一部分。
问题是,这段代码属于哪里?如果我把它放在Search.jsx
中,我会将操作与组件结合起来,对redux
更重要。
我应该有两个不同版本的组件,一个解耦,一个connect()
编辑并使用{{1}}来使用它吗?如果是的话,我的文件树会是什么样子?每个组件一个文件或类似<Menu />
?
答案 0 :(得分:11)
在redux中,存在一种称为容器的新组件,这是使用connect(mapStateToProps,mapActionsToProps)将组件和操作传递给当前组件的组件。
全部取决于组件的使用。例如,如果组件搜索仅用于相同的状态和操作,那么您的组件可能与您的组件相同:
// Search.jsx
import { connect } from 'redux'
import actions from 'actions'
import React from 'react'
import { className } from './search.scss'
class Search extends React.Component {
render () {
let { searchTerm, onSearch } = this.props
return (
<div className={`search ${className}`}>
<p>{searchTerm}</p>
<input
type='search'
onChange={(e) => onSearch(e.target.value)}
value={searchTerm}
/>
</div>
)
}
}
Search.propTypes = {
searchTerm: React.PropTypes.string,
onSearch: React.PropTypes.function
}
function mapStateToProps ({searchTerm}) {
return {
searchTerm
};
}
const mapDispatchToProps = {
onSearch: actions.search
}
export default connect(mapStateToProps, mapDispatchToProps)(Search)
但是,如果您的计划在另一个容器中重用此组件,并且searchTerm或该操作在全局状态上是不同的。最好的方法是将此属性传递给其他容器,并使搜索组件保持纯净。像这样:
// Container1.jsx
import { connect } from 'redux'
import actions from 'actions'
import React, { Component } from 'react'
class Container1 extends Component {
render() {
const { searchTerm, handleOnSearch } = this.props;
return (
<div>
<Search searchTerm={searchTerm} onSearch={handleOnSearch} />
</div>
)
}
}
function mapStateToProps ({interState: {searchTerm}}) {
return {
searchTerm
};
}
const mapDispatchToProps = {
handleOnSearch: actions.search
}
export default connect(mapStateToProps, mapDispatchToProps)(Container1)
// Container2.jsx
import { connect } from 'redux'
import otherActions from 'otheractions'
import React, { Component } from 'react'
class Container2 extends Component {
render() {
const { searchTerm, handleOnSearch } = this.props;
return (
<div>
<Search searchTerm={searchTerm} onSearch={handleOnSearch} />
</div>
)
}
}
function mapStateToProps ({otherState: {searchTerm}}) {
return {
searchTerm
};
}
const mapDispatchToProps = {
handleOnSearch: otherActions.search
}
export default connect(mapStateToProps, mapDispatchToProps)(Container2)