react组件间的传值方法

关于react的几个网站:

http://react.css88.com/

小书:http://huziketang.mangojuice.top/books/react/

http://www.redux.org.cn/

组件传值的方法:

1.父子组件间的传值

2.context

3.子组件向父组件传值

4.没有任何嵌套关系的组件之间传值

5.redux

一、父子组件间的传值(主要是利用 props 来进行交流,父组件用this.state传值,子组件用this.prop):

如果组件嵌套层次太深,那么从外到内组件的交流成本就变得很高,通过 props 传递值的优势就不那么明显了。

Father.jsx文件

import React, {Component} from 'react'

import Son from './Son.jsx'

{/*引入子组件*/}

export default class Father extends Component{

constructor(){

super();

this.state = {

message: 'hello',

sonVal: null

}

}

render(){

return (

<div >

<h1>Father组件</h1>

<button onClick={()=>{this.setState({message: 'world'})}}>

修改

</button>

{/* <Son data="test data value"/> */}

<p>选择了那种水果:{this.state.sonVal}</p>

<Son data={this.state.message} handle={this.testAction.bind(this)}/>

{/*子组件中传递参数或者方法*/}

</div>

)

}

// 接收子组件数据

testAction(value){

console.log(this);

console.log(value);

this.setState({sonVal: value});

} }

Son.jsx

import React, {Component} from 'react'

export default class Son extends Component{

constructor(){

super();

this.state = {

select: '苹果'

}

}

render(){

let arr = ['苹果', '香蕉', '西瓜'];

return (

<div >

<h1>Son组件</h1>

<p>接收到的值为:{this.props.data}</p>

{

arr.map((item, index)=>{

return (

<p key={index}>

{item}:

<input type="radio" value={item}

checked={this.state.select == item}

onChange={this.inputChange.bind(this)}/>

</p>

)

})

}

</div>

)

}

inputChange(ev){

let value = ev.target.value;

this.setState({select: value});

// 调用父组件的方法,将值传递给父组件

this.props.handle(value);

}

}

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

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

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

var Button = React.createClass({

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

contextTypes: {

color: React.PropTypes.string

},

render: function() {

return (

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

{this.props.children}

</button>

);

}

});

var Message = React.createClass({

render: function() {

return (

<div>

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

</div>

);

}

});

var MessageList = React.createClass({

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

childContextTypes: {

color: React.PropTypes.string

},

getChildContext: function() {

return {color: "purple"};

},

render: function() {

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

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

});

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

}

});

三、子组件向父组件传值

【子组件】控制自己的 state 然后告诉【父组件】的点击状态,然后在【父组件】中展示出来

// 父组件

var MyContainer = React.createClass({

getInitialState: function () {

return {

checked: false

};

},

onChildChanged: function (newState) {

this.setState({

checked: newState

});

},

render: function() {

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

return (

<div>

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

<ToggleButton text="Toggle me"

initialChecked={this.state.checked}

callbackParent={this.onChildChanged}

/>

</div>

);

}

});

// 子组件

var ToggleButton = React.createClass({

getInitialState: function () {

return {

checked: this.props.initialChecked

};

},

onTextChange: function () {

var newState = !this.state.checked;

this.setState({

checked: newState

});

// 这里要注意:setState 是一个异步方法,所以需要操作缓存的当前值

this.props.callbackParent(newState);

},

render: function () {

// 从【父组件】获取的值

var text = this.props.text;

// 组件自身的状态数据

var checked = this.state.checked;

return (

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

);

}

});

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

推荐一个相关博客:https://blog.csdn.net/u011439689/article/details/51955991

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

One.jsx文件

import React, {Component} from 'react'

import PubSub from 'pubsub-js'

export default class One extends Component{

constructor(){

super();

console.log('constructor');

this.state = {

message: null

}

}

render(){

console.log('render');

return (

<div>

<h1>One组件</h1>

<p>接收到的值为:{this.state.message}</p>

</div>

)

}

// 创建并且渲染完成的方法

componentDidMount(){

console.log('componentDidMount');

//监听子组件的事件

this.token = PubSub.subscribe('send-data', (eventName, data)=>{

console.log('subscribe执行了');

console.log(data);

this.setState({message: data});

})

// $on

}

//组件将要销毁

componentWillUnmount(){

console.log('componentWillUnmount');

// 组件销毁时,需要移除监听

PubSub.unsubscribe(this.token);

// $off

}

}

Two.jxs

import React, {Component} from 'react'

import PubSub from 'pubsub-js'

export default class Two extends Component{

render(){

return (

<div>

<h1>Two组件</h1>

<input type="text" ref="in"/>

<button onClick={this.sendAction.bind(this)}>发送</button>

</div>

)

}

sendAction(){

// 发送信息给one组件

PubSub.publish('send-data', this.refs.in.value);

// $emit

}

}

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

如果是比较大型的项目,可以使用react-redux,这方面的资料可以参考阮一峰的网络日志。

http://github.com/mroderick/PubSubJS

地址:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html