我看到了两种做同样事情的方法,但我不确定什么是正确的方法。
组件
import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {selectUser} from '../actions/index'
class UserList extends Component {
renderList() {
return this.props.users.map((user) => {
return (
<li
key={user.id}
onClick={() => this.props.selectUser(user)}
>
{user.first} {user.last}
</li>
);
});
}
render() {
return (
<ul>
{this.renderList()}
</ul>
);
}
}
// Get apps state and pass it as props to UserList
// > whenever state changes, the UserList will automatically re-render
function mapStateToProps(state) {
return {
users: state.users
};
}
// Get actions and pass them as props to to UserList
// > now UserList has this.props.selectUser
function matchDispatchToProps(dispatch){
return bindActionCreators({selectUser: selectUser}, dispatch);
}
// We don't want to return the plain UserList (component) anymore, we want to return the smart Container
// > UserList is now aware of state and actions
export default connect(mapStateToProps, matchDispatchToProps)(UserList);
https://github.com/buckyroberts/React-Redux-Boilerplate
或者
import React from "react"
import { connect } from "react-redux"
import { fetchUser } from "../actions/userActions"
import { fetchTweets } from "../actions/tweetsActions"
@connect((store) => {
return {
user: store.user.user,
userFetched: store.user.fetched,
tweets: store.tweets.tweets,
};
})
export default class Layout extends React.Component {
componentWillMount() {
this.props.dispatch(fetchUser())
}
fetchTweets() {
this.props.dispatch(fetchTweets())
}
render() {
const { user, tweets } = this.props;
if (!tweets.length) {
return <button onClick={this.fetchTweets.bind(this)}>load tweets</button>
}
const mappedTweets = tweets.map(tweet => <li>{tweet.text}</li>)
return <div>
<h1>{user.name}</h1>
<ul>{mappedTweets}</ul>
</div>
}
}
https://github.com/learncodeacademy/react-js-tutorials/tree/master/5-redux-react
第一种方式使用2个不同的函数mapStateToProps()
和matchDispatchToProps()
,而另一种方式使用@ connect(....).
当我使用@connect时,我收到一大堆警告,说它尚未最终确定并且可能会发生变化。
答案 0 :(得分:1)
我认为第一种方法最终会给你带来较少的问题。其他人也可以插话。
答案 1 :(得分:1)
@
符号是装饰者,仍然被认为是实验性的。所以我会自己冒风险使用它。您的第一个代码块是更安全的方式,如官方文档中所述。两个块基本上都做同样的事情,但装饰器比任何东西都更多糖。
参考文献:
答案 2 :(得分:0)
杰克逊的答案在任何意义上都是正确的,但是他错过了使用第一个版本进行单元测试的重要性。如果您希望能够对组件进行单元测试(通常意味着使用未连接的版本进行测试),则需要能够导出已连接和未连接的组件。
使用你的例子并假设你正在使用jest / enzyme,你可以这样做:
// notice importing the disconnected component
import { UserList } from '../relative/file/path/UserList'
import { mount } from 'enzyme'
describe('UserList', () => {
it('displays the Username', () => {
const users = [{fist: 'Person', last: 'Thing'}, ... ]
const UserList = mount(<UserList users={users} />)
export(UserList.find('li')[0].text()).toEqual('Person Thing')
});
});
一旦你建立了更大的项目,能够进行单元测试将为你的编码生活提供理智。希望这有帮助