Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于react-redux中的Provider传值 #57

Open
ckinmind opened this issue Jan 24, 2017 · 4 comments
Open

关于react-redux中的Provider传值 #57

ckinmind opened this issue Jan 24, 2017 · 4 comments

Comments

@ckinmind
Copy link
Owner

问题:

  1. Provider传递的store值是使得所有子组件能够访问到store还是所有容器组件?
@ckinmind
Copy link
Owner Author

参考资料:redux必须用<Provider store={store} 这样传递全局的store吗?

react-redux 是官方提供的解决方案,Provider 本身并没有做很多事情,只是把 store 放在 context 里罢了。实际上如果你用 react-redux,那么连接视图和数据层最好的办法是使用 connect 函数。本质上 Provider 就是给 connect 提供 store 用的

这里的重点是Provider就是提供给connect(这里的意思应该是容器组件)store用的

@ckinmind
Copy link
Owner Author

参考资料:Redux-Provider与connect

1)入口文件中,store被传入Provider,但是子组件中并没有直接使用store,但是却具有dispatch方法(dispatch是store对象上的一个方法),Provider做了什么?
2)最外层组件中,export default connect(select)(App)是怎样联系Redux和React的?
3)dispatch(actions creators(data))是事件的发布者,但是store是什么时候被监听的?
4)reducer中并没有调用React的this.setState方法,页面到底是如何被render的?
5)既然Redux可以render页面,我们还要不要手动在callback中写this.setState?

解答:
Provider干的事:接收store,并将store传到子组件中,当store发生变化时,更新store;所以子组件具有store的dispatch方法。问题1)解决

connect干的事:定义了一个新的组件Connect,经过一系列的merge后,将各种值挂载props上传递到原组件。 Connect组件会保存state状态,同时监听Redux Store的变化,从而触发原组件的更新。在componentDidMount中监听Provider提供的store的变化。通过Context来访问store。响应函数为handleChange,handleChange里接收到通知后,将Connect组件的state改变为新的state,这里会有调用this.setState的操作。问题2)3)4)初步解决

最后一个问题,官方说法是,既然用了Redux就应该用Redux控制所有状态,不手动render页面;也有人说不应该拘泥于API,在合适的时候可以调用this.setState方法,也确实有些例子是这么做的;StackOverflow的一个回答这么说:需要保存在全局sore中的state需要使用Redux,但是一些展示性的state(比如一个用来表示下拉框是否显示的Boolean值)可以使用this.setState来render页面。问题5)有待继续探索

@ckinmind
Copy link
Owner Author

参考资料: React实战-深入源码了解Redux用法之Provider

Provider源码

export default class Provider extends Component {
  getChildContext() {
    return { store: this.store }
  }
 
  constructor(props, context) {
    super(props, context)
    this.store = props.store
  }
  render() {
    return Children.only(this.props.children)
  }
}

上面的代码可以看出Provider是通过getChildContext的的方式传递给子组件的,并且我们也在connect中看到子组件取数据的过程

constructor(props, context) {
        super(props, context)
        this.version = version
        this.store = props.store || context.store
.......
}

@ckinmind
Copy link
Owner Author

参考资料:React 实践心得:react-redux 之 connect 方法详解

Provider 内的任何一个组件(比如这里的 Comp ),如果需要使用 state 中的数据,就必须是「被 connect 过的」组件——使用 connect 方法对「你编写的组件( MyComp )」进行包装后的产物

这是的意思是只有容器组件才能访问到store中的数据,UI组件需要通过容器组件传递(通过connect方法中的mapStateToProps和mapDispatchToProps传递)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant