react组件间的传值方法

摘要:
指定数据并希望传递数据的父组件应该定义childContextTypes和getChildContext();想要接收数据的子组件必须定义contextType以使用传递的上下文。

关于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文件

importReact, {Component} from'react'
importSonfrom'./Son.jsx'
{/*引入子组件*/}
exportdefaultclassFatherextendsComponent{

constructor(){

super();
this.state = {
message:'hello',
sonVal:null
}
}
render(){
return (
<divid="father">
<h1>Father组件</h1>
<buttononClick={()=>{this.setState({message:'world'})}}>
修改
</button>
{/* <Son data="test data value"/> */}
<p>选择了那种水果:{this.state.sonVal}</p>
<Sondata={this.state.message}handle={this.testAction.bind(this)}/>

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


</div>
)
}

// 接收子组件数据
testAction(value){
console.log(this);
console.log(value);
this.setState({sonVal:value});
} }

Son.jsx

importReact, {Component} from'react'
exportdefaultclassSonextendsComponent{
constructor(){
super();
this.state = {
select:'苹果'
}
}
render(){
letarr = ['苹果', '香蕉', '西瓜'];
return (
<divid="son">
<h1>Son组件</h1>
<p>接收到的值为:{this.props.data}</p>
{
arr.map((item, index)=>{
return (
<pkey={index}>
{item}:
<inputtype="radio"value={item}
checked={this.state.select == item}
onChange={this.inputChange.bind(this)}/>
</p>
)
})
}
</div>
)
}
inputChange(ev){
letvalue = 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 。
varButton = React.createClass({
// 必须指定context的数据类型
contextTypes: {
color:React.PropTypes.string
},
render:function() {
return (
<buttonstyle={{background:this.context.color}}>
{this.props.children}
</button>
);
}
});
 
varMessage = React.createClass({
render:function() {
return (
<div>
{this.props.text}<Button>Delete</Button>
</div>
);
}
});
 
varMessageList = React.createClass({
//父组件要定义 childContextTypes 和 getChildContext()
childContextTypes: {
color:React.PropTypes.string
},
getChildContext:function() {
return {color:"purple"};
},
render:function() {
varchildren = this.props.messages.map(function(message) {
return<Messagetext={message.text}/>;
});
return<div>{children}</div>;
}
});

三、子组件向父组件传值

【子组件】控制自己的 state 然后告诉【父组件】的点击状态,然后在【父组件】中展示出来
// 父组件
varMyContainer = React.createClass({
getInitialState:function () {
return {
checked:false
};
},
onChildChanged:function (newState) {
this.setState({
checked:newState
});
},
render:function() {
varisChecked = this.state.checked ? 'yes' : 'no';
return (
<div>
<div>Are you checked: {isChecked}</div>
<ToggleButtontext="Toggle me"
initialChecked={this.state.checked}
callbackParent={this.onChildChanged}
/>
</div>
);
}
});
 
// 子组件
varToggleButton = React.createClass({
getInitialState:function () {
return {
checked:this.props.initialChecked
};
},
onTextChange:function () {
varnewState = !this.state.checked;
this.setState({
checked:newState
});
// 这里要注意:setState 是一个异步方法,所以需要操作缓存的当前值
this.props.callbackParent(newState);
},
render:function () {
// 从【父组件】获取的值
vartext = this.props.text;
// 组件自身的状态数据
varchecked = this.state.checked;
 
return (
<label>{text}: <inputtype="checkbox"checked={checked}onChange={this.onTextChange}/></label>
);
}
});

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

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

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

 One.jsx文件

importReact, {Component} from'react'
importPubSubfrom'pubsub-js'
exportdefaultclassOneextendsComponent{
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

importReact, {Component} from'react'
importPubSubfrom'pubsub-js'
exportdefaultclassTwoextendsComponent{
render(){
return (
<div>
<h1>Two组件</h1>
<inputtype="text"ref="in"/>
<buttononClick={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

免责声明:文章转载自《react组件间的传值方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Sql 本周当天本期日期转换DNS_PROBE_FINISHED_NO_INTERNET 之解决下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【abp vnext 实战系列】简单的内容管理系统:搭建框架

PS:中文文档地址 1- 生成项目的方式 1.1- 模板生成地址 https://abp.io/get-started 1.2-abp cli 命令生成 https://docs.abp.io/zh-Hans/abp/latest/Getting-Started?UI=MVC&DB=EF&Tiered=No 2-项目结构 PS:我是纯手工制...

Spring batch学习 详细配置解读(3)

     第一篇讲到普通job 配置 那么spring  batch 给我们提供了丰富的配置,包括定时任务,校验,复合监听器,父类,重启机制等。              下面看一个动态设置读取文件的配置                 1.动态文件读取            <?xml version="1.0" encoding="UTF-8"?...

react中用swiper实现大图功能

1.引入Swiper(用的是4.5.0版本) import Swiper from 'swiper'; //引入样式,还可以加上自己的样式 import '../../style/swiper.min.css'; 2.在页面加载后和获取完数据后new一个swiper(如果数据没加载完就new会出现不能滑动现象) new Swiper('.swiper-...

asp.net core mvc剖析:mvc动作选择

一个http请求过来后,首先经过路由规则的匹配,找到最符合条件的的IRouter,然后调用IRouter.RouteAsync来设置RouteContext.Handler,最后把请求交给RouteContext.Handler来处理。在MVC中提供了两个IRouter实现,分别如下: 1,MvcAttributeRouteHandler 2,MvcRou...

.NET Core授权失败如何自定义响应信息?

前言 在.NET 5之前,当授权失败即403时无法很友好的自定义错误信息,以致于比如利用Vue获取到的是空响应,不能很好的处理实际业务,同时涉及到权限粒度控制到控制器、Action,也不能很好的获取对应路由信息。本文我们来看看在.NET 5中为何要出现针对授权失败的中间件接口?它是如何一步步衍生出来的呢?以及对于授权失败根据实际需要如何自定义响应错误,以及...

结对项目:一寸时光APP(日程管理)二

建立数据库 package com.example.myapplication3.db; import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLi...