如何在React中使用Redux的Provider

56

我一直在遵循ReduxJS文档,这里是React使用方法

文档末尾提到了provider对象的用法,我已经像这样将我的App组件包裹在提供程序中:

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import RootReducer from './app/reducers'
import App from './app/app'

const store = createStore(RootReducer)

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

然而,文档到此结束。我该如何在组件中获取由提供程序提供的存储?


1
它向您展示了如何在教程早期将组件连接到存储 - 查看标记为“容器组件”的部分。 - Joe Clay
2
@JoeClay 所以你仍然需要使用 connect 吗? - Jacob Mason
3
“connect” 是最好/最可靠的方法来实现它,除非你有非常好的理由去使用更低层级的方式(该指南提到“connect”拥有额外的性能优化)。话虽如此,如果你真的想直接访问存储器,则“Provider”使得所有子组件都可以通过上下文进行访问 - 在你的组件内部,使用“this.context.store”应该返回这个实例。 - Joe Clay
我会写一个更好格式化的版本作为答案,并附上一些示例。 - Joe Clay
@JacobMason,如果没有将根组件包装在<Provider>中,您无法使用connect() - lngs
https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store - lngs
2个回答

57

通过使用 connect() 函数是访问组件中存储库最佳方式,文档中有详细描述。这使您可以将状态和操作创建器映射到组件,并在存储库更新时自动传递它们。此外,默认情况下,它将以 this.props.dispatch 的形式传递 dispatch。以下是文档中的示例:

import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'

const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.filter === state.visibilityFilter
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch(setVisibilityFilter(ownProps.filter))
    }
  }
}

const FilterLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

export default FilterLink
注意,connect实际上创建了一个包装现有组件的新组件!这种模式称为Higher-Order Components(高阶组件),通常是在React中扩展组件功能的首选方式(而不是继承或混入等方法)。
由于它具有许多性能优化,并且通常不太可能引起错误,因此Redux的开发人员几乎总是建议使用connect而不是直接访问存储库 - 但是,如果您有一个非常好的理由需要更低级别的访问,则Provider组件使其所有子代都可以通过this.context访问存储库:
class MyComponent {
  someMethod() {
    doSomethingWith(this.context.store);
  }
}

14
不知道该用什么关键词搜索真是太糟糕了。我需要的是 this.context。详情请参考:https://facebook.github.io/react/docs/context.html。 - Freedom_Ben
ownProps.filter是什么?在todo示例中的Link组件中我没有看到filter属性。 - SuperUberDuper
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Joe Clay
@SuperUberDuper:当JSX被编译时,<Component />会变成React.createElement(Component)。因此从技术上讲,它确实被使用了,只是不太明显 :) - Joe Clay
@SuperUberDuper:是的,我认为很多人一开始都会被这个绊倒。 - Joe Clay
显示剩余4条评论

17
感谢您的回答,但是它缺少一个至关重要的部分,该部分实际上在文档中已经有了。

如果未定义contextTypes,则context将是一个空对象。

因此,我不得不添加以下内容才能让它对我起作用:
  static contextTypes = {
    store: PropTypes.object.isRequired
  }

在组件中使用什么?例如在渲染函数中,this.contextTypes.store.getState() - R01010010
是的,这是在组件内部。 并且在render()方法内使用: this.context.store - amahfouz
哇,我被困在这个问题上整整一周了! - Pete Alvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接