React组件间信息传递方式

谈及React时,就会想到一个很重要的思想,就是组件化思想。它将可以重用的部分进行组件化开发,形成一个个相对独立的组件,那么组件化后,你也会提出些疑问,组件与组件之间,将怎样进行信息的传递呢?下面来介绍下组件之间传递信息的方法。

 

    组件之间传递信息方式,总体可分为以下5种:

1.(父组件)向(子组件)传递信息

2.(父组件)向更深层的(子组件) 进行传递信息  >>利用(context)

3.(子组件)向(父组件)传递信息

4.没有任何嵌套关系的组件之间传值(比如:兄弟组件之间传值)

5.利用react-redux进行组件之间的状态信息共享

 

下面结合实例详细说明种传递信息的方式。

以下的例子都是比较经典的例子,看过后加入了我的个人见解,希望对你们有所帮助。

 

   一.(父组件)向(子组件)传递信息 >>>主要是通过 prop进行传值

        来看下面的例子

 

 
  1. //父组件

  2. var MyContainer = React.createClass({

  3. getInitialState: function () {

  4. return {

  5. checked: false

  6. };

  7. },

  8. render: function() {

  9. return (

  10. <ToggleButton text="Toggle me" checked={this.state.checked} />

  11. );

  12. }

  13. });

  14.  
  15. // 子组件

  16. var ToggleButton = React.createClass({

  17. render: function () {

  18. // 从(父组件)获取的值

  19. var checked = this.props.checked,

  20. text = this.props.text;

  21.  
  22. return (

  23. <label>{text}: <input type="checkbox" checked={checked} /></label>

  24. );

  25. }

  26. });

 

以上这个例子,子组件通过 prop拿到了text值以及checked的属性值;那么当子组件要拿到祖父级组件的信息,也是可以通过prop进行逐层的获取。来看下下面的例子。

官方文档的示例代码如下:

       

 
  1. var Button = React.createClass({

  2. render: function() {

  3. return (

  4. <button style={{background: this.props.color}}>

  5. {this.props.children}

  6. </button>

  7. );

  8. }

  9. });

  10.  
  11. var Message = React.createClass({

  12. render: function() {

  13. return (

  14. <div>

  15. {this.props.text} <Button color={this.props.color}>Delete</Button>

  16. </div>

  17. );

  18. }

  19. });

  20.  
  21. var MessageList = React.createClass({

  22. render: function() {

  23. var color = "purple";

  24. var children = this.props.messages.map(function(message) {

  25. return <Message text={message.text} color={color} />;

  26. });

  27. return <div>{children}</div>;

  28. }

  29. });


以上的例子中第一层组件(MessageList)想要将color值传递到第三层组件(Button),通过第二层组件(Message)进行了传递。进而实现了。但是这种方式,并不是很优雅,如果传递的层级更多时,中间的层级都需要来传递,数据的传递变的更加繁琐。所以我们就会想到,是否可以"越级"获取数据。这时候就需要使用context。能帮你 "越级" 传递数据到组件中你想传递到的深层次组件中。
 

 

  二.(父组件)向更深层的(子组件) 进行传递信息  >>利用(context)

利用context,改进后的代码如下:

  

 
  1. var Button = React.createClass({

  2. // 必须指定context的数据类型

  3. contextTypes: {

  4. color: React.PropTypes.string

  5. },

  6. render: function() {

  7. return (

  8. <button style={{background: this.context.color}}>

  9. {this.props.children}

  10. </button>

  11. );

  12. }

  13. });

  14.  
  15. var Message = React.createClass({

  16. render: function() {

  17. return (

  18. <div>

  19. {this.props.text} <Button>Delete</Button>

  20. </div>

  21. );

  22. }

  23. });

  24.  
  25. var MessageList = React.createClass({

  26. //父组件要定义 childContextTypes 和 getChildContext()

  27. childContextTypes: {

  28. color: React.PropTypes.string

  29. },

  30. getChildContext: function() {

  31. return {color: "purple"};

  32. },

  33. render: function() {

  34. var children = this.props.messages.map(function(message) {

  35. return <Message text={message.text} />;

  36. });

  37. return <div>{children}</div>;

  38. }

  39. });

 

以上代码中通过添加 childContextTypes 和 getChildContext() 到 第一层组件MessageList ( context 的提供者),React 自动向下传递数据然后在组件中的任意组件(也就是说任意子组件,在此示例代码中也就是 Button )都能通过定义 contextTypes(必须指定context的数据类型) 访问 context 中的数据。这样就不需要通过第二层组件进行传递了。

指定数据并要将数据传递下去的父组件要定义 childContextTypes 和 getChildContext() ;想要接收到数据的子组件 必须定义 contextTypes 来使用传递过来的 context 。


 

    三.(子组件)向(父组件)传递信息

来看下面的例子

 

 
  1. // 父组件

  2. var MyContainer = React.createClass({

  3. getInitialState: function () {

  4. return {

  5. checked: false

  6. };

  7. },

  8. onChildChanged: function (newState) {

  9. this.setState({

  10. checked: newState

  11. });

  12. },

  13. render: function() {

  14. var isChecked = this.state.checked ? 'yes' : 'no';

  15. return (

  16. <div>

  17. <div>Are you checked: {isChecked}</div>

  18. <ToggleButton text="Toggle me"

  19. initialChecked={this.state.checked}

  20. callbackParent={this.onChildChanged}

  21. />

  22. </div>

  23. );

  24. }

  25. });

  26.  
  27. // 子组件

  28. var ToggleButton = React.createClass({

  29. getInitialState: function () {

  30. return {

  31. checked: this.props.initialChecked

  32. };

  33. },

  34. onTextChange: function () {

  35. var newState = !this.state.checked;

  36. this.setState({

  37. checked: newState

  38. });

  39.  
  40. //这里将子组件的信息传递给了父组件

  41. this.props.callbackParent(newState);

  42. },

  43. render: function () {

  44. // 从(父组件)获取的值

  45. var text = this.props.text;

  46. // 组件自身的状态数据

  47. var checked = this.state.checked;

  48. //onchange 事件用于单选框与复选框改变后触发的事件。

  49. return (

  50. <label>{text}: <input type="checkbox" checked={checked} onChange={this.onTextChange} /></label>

  51. );

  52. }

  53. });


 

 

以上例子中,在父组件绑定callbackParent={this.onChildChanged},在子组件利用this.props.callbackParent(newState),触发了父级的的this.onChildChanged方法,进而将子组件的数据(newState)传递到了父组件。
这样做其实是依赖 props 来传递事件的引用,并通过回调的方式来实现的。

 

 四.没有任何嵌套关系的组件之间传值(比如:兄弟组件之间传值)

如果组件之间没有任何嵌套关系,组件嵌套层次比较深,我们该怎样去传递信息呢?

下面来看一个例子

这个例子需要引入一个PubSubJS 库,通过这个库你可以订阅的信息,发布消息以及消息退订。
PubSubJS 具体可参考下面的内容http://blog.csdn.net/u011439689/article/details/51955991

 

 

 
  1. // 定义一个容器(将ProductSelection和Product组件放在一个容器中)

  2. var ProductList = React.createClass({

  3. render: function () {

  4. return (

  5. <div>

  6. <ProductSelection />

  7. <Product name="product 1" />

  8. <Product name="product 2" />

  9. <Product name="product 3" />

  10. </div>

  11. );

  12. }

  13. });

  14. // 用于展示点击的产品信息容器

  15. var ProductSelection = React.createClass({

  16. getInitialState: function() {

  17. return {

  18. selection: 'none'

  19. };

  20. },

  21. componentDidMount: function () {

  22. //通过PubSub库订阅一个信息

  23. this.pubsub_token = PubSub.subscribe('products', function (topic, product) {

  24. this.setState({

  25. selection: product

  26. });

  27. }.bind(this));

  28. },

  29. componentWillUnmount: function () {

  30. //当组件将要卸载的时候,退订信息

  31. PubSub.unsubscribe(this.pubsub_token);

  32. },

  33. render: function () {

  34. return (

  35. <p>You have selected the product : {this.state.selection}</p>

  36. );

  37. }

  38. });

  39.  
  40. var Product = React.createClass({

  41. onclick: function () {

  42. //通过PubSub库发布信息

  43. PubSub.publish('products', this.props.name);

  44. },

  45. render: function() {

  46. return <div onClick={this.onclick}>{this.props.name}</div>;

  47. }

  48. });


 

 

ProductSelection和Product本身是没有嵌套关系的,而是兄弟层级的关系。但通过在ProductSelection组件中订阅一个消息,在Product组件中又发布了这个消息,使得两个组件又产生了联系,进行传递的信息。所以根据我个人的理解,当两个组件没有嵌套关系的时候,也要通过全局的一些事件等,让他们联系到一起,进而达到传递信息的目的。

 

 五.利用react-redux进行组件之间的状态信息共享

如果是比较大型的项目,可以使用react-redux,这方面的资料可以参考阮一峰的网络日志。
地址:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.

 

以上的例子,都可以实际尝试一下。在实际项目中,可以根据实际的情况选取相应的解决办法。最后,希望我的介绍能够对你有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值