react-redux:你如何从任何地方访问商店'没有导入它?

时间:2017-03-27 19:35:30

标签: reactjs react-redux

在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

1 个答案:

答案 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>
    );
  }
}

请注意,您从不必参考商店。