在react-redux文档中,它指出在使用React-redux和connect()
时不建议导入存储。这是一种反模式。
http://redux.js.org/docs/faq/StoreSetup.html
同样,您可以通过导入来引用商店实例 直接,这不是Redux中推荐的模式。如果你创建一个 存储实例并从模块中导出它,它将成为一个 单身。这意味着将Redux应用程序隔离为更难 更大的应用程序的组件,如果有必要,或启用 服务器渲染,因为在服务器上要创建单独的 存储每个请求的实例。
使用React Redux,connect()生成的包装类 函数实际上寻找props.store,如果它存在,但它是最好的 如果你将你的根组件包装好并让它 React Redux担心将商店放下。这种方式组件 不需要担心导入商店模块,并隔离a 稍后,Redux应用程序或启用服务器呈现更容易。
在我store
正确连接到我的应用后,如何从我选择的任何组件(甚至在应用程序的深处)访问store
?我的代码正确连接了App
,但我无法从任何子组件访问商店。 store.dispatch()
为空,store.getState()
为空,等等。我觉得文档在这方面缺乏。它被说成是魔术,但我想知道如何使用魔法。我是否需要为每个容器组件一次又一次地编写mapDispatchToProps()
?用例将是currentUser
prop,它可供应用程序中的每个子组件使用。我想将其从App
传递给每个孩子。
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);//App is now a connected component, that part is working
在App
内部,我有一个Login
组件,我想在其中加dispatch
action
。但我需要提及store
,但显然我不应该import
。
答案 0 :(得分:4)
这就是containers的概念发挥作用的地方。
假设您要在Login
内呈现App
组件。您将创建连接容器。
第1步是创建一个简单的动作:
const LOGIN_ATTEMPT = 'auth/LOGIN_ATTEMPT';
export const login = name => ({
type: LOGIN_ATTEMPT,
payload: { name },
});
现在,您将使用react-redux
将此操作连接到“演示组件”。这将作为prop
发布到组件。
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { login } from 'actions/auth'; // your action
import Login from 'components/auth/Login'; // your component to connect it to.
// state refers to the "current state" of your store.
const mapStateToProps = state => ({ currentUser: state.auth.user });
// dispatch refers to `store.dispatch`
const mapDispatchToProps = dispatch => {
// calling this is like calling `store.dispatch(login(...params))`
login: bindActionCreators(login, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Login);
此connect
函数将这两个函数作为参数。您现在可以导入此连接的容器,并将其与作为属性“绑定”的函数一起使用。
以下示例组件。
export default class Login extends Component {
static propTypes = {
// properties below come from connect function above.
currentUser: PropTypes.shape({
name: PropTypes.string.isRequired,
}).isRequired,
login: PropTypes.func.isRequired,
};
state = { name: "" };
onChange = ({ target: { value: name } }) => this.setState({ name });
onSubmit = e => {
e.preventDefault();
login(this.state.name);
};
render() {
return (
<form onSubmit={this.onSubmit}>
<input
placeholder="name"
onChange={this.onChange}
value={this.state.name}
/>
</form>
);
}
}
请注意,您从不必参考商店。