我有一个反应(使用redux& react-router)应用程序,在不同的点需要知道用户是否根据商店中某些数据的状态登录,以及其他一些与之相关的事情商店里的数据。
为实现这一目标,我创建了一个更高阶的组件,如下所示:
import React from 'react';
import {connect} from 'react-redux';
export function masterComponent(Component){
class MasterComponent extends React.Component {
constructor(props){
super(props);
}
loggedIn(){
return this.props.player.token? true : false
}
render(){
return (
<Component {...this.props} player={{loggedIn: this.loggedIn()}}/>
);
}
}
UserComponent.propTypes = {
player: React.PropTypes.object
};
function mapStateToProps(state) {
return state;
}
return connect(
mapStateToProps
)(MasterComponent);
}
我的问题是如何围绕我的个人组件进行包装?目前我已经实现了它,以便每个单独的组件在传递给connect时被包装,它工作正常,但感觉效率有点低。即:
import {masterComponent} from '../HigherOrderComponents/MasterComponent';
export class ResultsPage extends React.Component {
constructor(props){
.....
}
render(){
return (
.....
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(masterComponent(ResultsPage));
有更好的方法吗?
答案 0 :(得分:2)
这取决于您的使用案例,我看到了3种可能的解决方案。下面的代码是未经测试和半伪的。
export function masterComponent(Component) {
const MasterComponent = (props) => {
const loggedIn = props.player.token? true : false;
// initial solution would override player, so you need
// something like this
const player = {
...this.props.player,
loggedIn,
};
return <Component {...this.props} player={player} />
}
// Important! Here is the crucial part of the refactoring,
// not the coding style changes. Map only the relevant
// state properties, otherwise the component would rerender
// whenever any state property changed.
return connect(state => ({ player: this.state.player }))(MasterComponent);
}
function loginMiddleware() {
return store => next => action => {
if (action.type === 'ADD_CREDENTIALS') {
const { player } = store.getState();
loginService.setPlayer(player);
}
// removePlayer if action.type === 'LOGOUT';
return next(action);
}
}
以及您可以使用的任何组件
loginService.getPlayer()
验证某人是否已登录
缺点与您的方法相比:如果已调度操作'ADD_CREDENTIALS'
,但请求loginService.getPlayer()
的组件未被重新呈现/更新,您可能会结束与不一致的状态。我确信你可以通过更具体的应用知识解决这个问题。
使用React context并将所需的属性传递给所有其他组件。