问题:IDE无法通过connect()
解析传递给组件的道具注意:这不是错误,但对编码人员造成不便
假设我已通过connect()
将此React组件连接到Redux:
class SomeComponent extends Component {
render() {
return (
{this.props.someObject ? this.props.someObject : ''}
);
}
}
function mapStateToProps(state) {
return {
someObject: new SomeObject(state.someReducer.someObjectInfo),
};
}
function mapDispatchToProps(dispatch) {
return {
// ...
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatsList);
我正在使用IntelliJ IDE,并且以上述方式连接到组件的任何道具(例如someObject
)都会收到未解决的变量警告。如果someObject
有一些属性/方法,它们既不会被解析也不会显示在代码建议中(这些都非常有用)。
解决方法
将state
和dispatch
自己作为道具传递:
function mapStateToProps(state) {return {state};}
function mapDispatchToProps(dispatch) {return {dispatch};}
在构造函数中定义我的变量(而不是通过道具):
constructor(props) {
this.someVar = props.state.someReducer.someVar;
this.someObj = new SomeObject(props.state.someReducer.someObjectInfo;
}
每当道具改变时手动更新变量:
componentWillReceiveProps(nextProps) {
someObject.update(nextProps.state.someReducer.someObjectInfo);
}
缺点是在componentWillReceiveProps
中有额外的样板逻辑,但现在IDE很乐意解析变量并且代码建议有效。
问题
解决方法更好吗?到目前为止,我一直在使用它,到目前为止还没有发现任何其他缺点。有没有更好的方法让IDE了解代码?
动机(详细;仅对那些对我为什么要完成上述工作感兴趣的人)
Redux教程展示了一种将状态/调度连接到道具的简单方法,例如:
function mapStateToProps(state) {
users: state.usersReducer.users
chats: state.chatsReducer.chats
}
function mapDispatchToProps(dispatch) {
addUser: (id) => dispatch(usersActions.addUser(id))
addChatMsg: (id, msg) => dispatch(chatsActions.addChatMsg(id, msg)
}
在上面的例子中,组件的编码器需要知道每个相关的减速器。名称及其状态变量。这对于编码人员来说可能会变得混乱。相反,我想从组件中抽象出这些细节。一种方法是使用"模块"接受state
和dispatch
的类,并提供所有get / set方法:
class Chats {
// Actions
static ADD_MESSAGE = "CHATS/ADD_MESSAGE";
constructor(globalState, dispatch) {
this.chatsState = globalState.chats;
this.dispatch = dispatch;
}
// Get method
getChats() {
return this.chatsState.chats;
}
// Set method
addChatMessage(id, msg) {
return this.dispatch({
type: Chats.ADD_MESSAGE,
id,
msg
};
}
// Called by componentWillReceiveProps to update this object
updateChats(nextGlobalState) {
this.chatsState = nextGlobalState.chats;
}
}
现在,如果一个组件需要Chats模块,编码器就会这样做:
class SomeComponent extends Component {
constructor(props) {
this.chats = new Chats(props.state, props.dispatch);
}
componentWillReceiveProps(nextProps) {
this.chats.updateChats(nextProps);
}
// ...
}
现在,所有Chats get / set方法和属性都可用,并且将被IDE选中。
答案 0 :(得分:0)
我认为最新的Idea现在可以理解通过propTypes定义的组件属性,并为它们提供代码完成。所以你只需声明propTypes。它甚至不是一种解决方法,在我看来这是一个很好的做法。
class ChatsList extends Component {
static propTypes = {
someObject: PropTypes.shape({
color: PropTypes.string,
someFunc: PropTypes.func
}),
someDispatcher: PropTypes.func
};
render() {
return (
{this.props.someObject ? this.props.someObject : ''}
);
}
}
function mapStateToProps(state) {
return {
someObject: new SomeObject(state.someReducer.someObjectInfo),
};
}
function mapDispatchToProps(dispatch) {
return {
someDispatcher: Actions.someDispatcher
// ...
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatsList);
此外,传递整个状态是一个坏主意,因为如果整个状态发生任何变化,组件将接收道具并获得重新渲染(除非您提供shouldComponentUpdate
)