我已将我的代码迁移到使用React(15.5.4),React Router v4(4.1.1),Redux(3.6.0),Immutable(3.8.1),现在我很难理解这个问题。
我使用Redux-auth(https://github.com/lynndylanhurley/redux-auth)作为我的应用验证的基础。它工作正常,直到我想要迁移react-router库。据我所知,auth变量没有传递给组件。在阅读了几篇博客文章后,似乎与萝卜似乎走了。我不知道如何使用它。任何帮助将不胜感激。
我使用Lynn的OAuthSignInButton代码,除了改变它的导出方式,因为根据我的理解,现在connect不能用于最新的迁移:
import { oAuthSignIn as _oAuthSignIn } from '../../actions/users/oauth-sign-in';
// hook for rewire
var oAuthSignIn = _oAuthSignIn;
class OAuthSignInButton extends React.Component {
static propTypes = {
provider: PropTypes.string.isRequired,
label: PropTypes.string,
signInParams: PropTypes.object,
children: PropTypes.node,
icon: PropTypes.node
};
static defaultProps = {
signInParams: {},
children: <span>OAuth Sign In</span>,
icon: <span></span>
};
getEndpoint() {
return (
this.props.endpoint ||
this.props.auth.getIn(['configure', 'currentEndpointKey']) ||
this.props.auth.getIn(['configure', 'defaultEndpointKey'])
);
}
handleClick() {
this.props.dispatch(oAuthSignIn({
provider: this.props.provider,
params: this.props.signInParams,
endpointKey: this.getEndpoint()
}))
.then(this.props.next)
.catch(() => {});
}
render() {
let disabled = this.props.auth.getIn(['user', 'isSignedIn']);
let loading = (
(this.props.auth.getIn(['ui', 'oAuthSignInLoadingProvider']) === this.props.provider) &&
this.props.auth.getIn(['oAuthSignIn', this.getEndpoint(), 'loading'])
);
return (
<ButtonLoader
loading={loading}
className={`${this.props.className} oauth-sign-in-submit`}
disabled={disabled}
onClick={this.handleClick.bind(this)}
{...this.props}
/>
);
}
}
export default OAuthSignInButton;
这是主要容器:
class Main extends React.Component {
static propTypes = {
dispatch: PropTypes.func,
pageEndpoint: PropTypes.string,
theme: PropTypes.string,
currentUserUid: PropTypes.string,
currentUserProvider: PropTypes.string,
currentUserEndpoint: PropTypes.string,
};
render() {
return (
<div>
<Theme.OAuthSignInButton
provider="facebook"
endpoint={this.props.pageEndpoint}
default
bsStyle="default"
style={{ padding: 0, borderStyle: 'none' }}
>
<img src={require('../assets/btn_facebook1.png')} />
</Theme.OAuthSignInButton>
</div>
);
}
}
export default Main;
Redux auth reducer看起来像这样:
import { combineReducers } from 'redux-immutable';
/* reducers */
export const authStateReducer = combineReducers({
configure,
oAuthSignIn,
ui,
user
});
我的一个减速器样本:
const initialState = Immutable.fromJS({
loading: true,
errors: null,
config: null,
endpointKeys: null,
defaultEndpointKey: null,
currentEndpointKey: null
});
export default function configureReducer(state = initialState, action) {
switch (action.type) {
case STORE_CURRENT_ENDPOINT_KEY:
return ({ currentEndpointKey }) => state.merge({ currentEndpointKey });
case SET_ENDPOINT_KEYS:
return ({ endpointKeys, defaultEndpointKey, currentEndpointKey }) => state.merge({
endpointKeys, defaultEndpointKey, currentEndpointKey
});
default:
return state;
}
}
主减速机:
import { combineReducers } from 'redux-immutable';
import { authStateReducer } from './users';
import { routerReducer } from 'react-router-redux';
export default (combineReducers({
auth: authStateReducer,
router: routerReducer
}));
Redux商店:
import { createStore, applyMiddleware } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import reducer from '../reducers';
const middleware = routerMiddleware(history);
const store = createStore(reducer, applyMiddleware(middleware));
export default store;
我的client.js文件如下所示:
import { AppContainer } from 'react-hot-loader';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import { Route } from 'react-router';
import Main from './containers/Main';
import store from './store';
const history = createHistory();
const render = Component => {
ReactDOM.render(
<AppContainer>
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Route exact path="/" component={Component} />
</div>
</ConnectedRouter>
</Provider>
</AppContainer>,
document.getElementById('content')
);
};
render(Main);
if (module.hot) {
module.hot.accept('./containers/Main', render);
}