React 页面间传值的个人总结
react 组件之间传值的方案有很多,下面是我个人经验的总结
github 地址
props 来传递值
传值方式:
- 通过props 获取值
- 通过props 提供的func去修改值
优点:
- 不需要任何第三方的组件,纯react,非常纯哦
缺点:
- 代码调试有些麻烦,但是可以react 插件辅助查看到当前react 对象的props
注意事项:
一般在表单页面中用到组件时候会用到props 传递值,需要注意下,最好页面的状态控制都在该页面的顶级节点的state 的,不要尝试获取或控制子节点的state,所以组件内部state是父级节点不关心的
Demo 代码如下:
import React,{Component} from 'react';
import PropTypes from 'prop-types'
class ChildNode extends Component{
static PropTypes={
value:PropTypes.string.isRequired,
onChange:PropTypes.func.isRequired
}
render(){
const {value,onChange} = this.props;
return (
<div>
<span>这里是子节点值:{value}</span><br/>
<input type="text" value={value} onChange={(e)=>{
console.log('开始更改值')
onChange(e.target.value)
}}/>
</div>
)
}
}
class Parent extends Component{
state={
childValue:'this is the value of the child node'
}
onChildValueChange=(val)=>{//注意这里用ES6 的array function 来绑定当前的this
this.setState({childValue:val})
}
render(){
const {childValue} = this.state;
return (
<div>
<span>这里是父节点</span>
<div>
<span>父节点控制子节点的内容</span>
<button onClick={()=>{
let childValue = this.state.childValue||""
this.setState({
childValue:childValue+'我最帅!'
})
}}>内容直接加上我最帅</button>
</div>
<br/>
<br/>
<ChildNode value={childValue} onChange={this.onChildValueChange}/>
</div>
)
}
}
export default Parent;
Redux
这里使用redux-react 来连接 react 和 redux。
传递方式:
获取值:通过redux-react connect()
传递值:通过dispatch 具体的action
优点:
- 可以通过redux-logger 组件来查看数据的变化过程,可以容易的调试复杂的业务逻辑
- 全局的数据都可以获取到以及修改
缺点:
- 因为业务独立逻辑代码独立到action、reducer里面,需要增加code的代码量以及单独action、reducer文件的分割。
可以借助文件夹名称的约定和第三方组件来弥补上面的缺点
注意事项
通过connect 传递过来的props 值不能修改哦。只读的!
Demo 代码如下:
import React,{Component} from 'react'
import {createStore,combineReducers} from 'redux'
import { Provider,connect } from 'react-redux'
/**
* reducer 用来描述state 是怎样改变的
* @param state
* @param action
* @returns {number}
*/
function reducerOne(state=0,action){
switch (action.type) {
case 'reducerOne/INCREMENT':
return state + 1
case 'reducerOne/DECREMENT':
return state - 1
default:
return state
}
}
const store = createStore(combineReducers({reducerOne}))
class ReduxNodeOne extends Component{
render(){
return (
<div>
<h6>节点一</h6>
<button onClick={()=>{
this.props.increment()
}}>加1</button>
<button onClick={()=>{
this.props.decrement()
}}>减1</button>
</div>
)
}
}
class ReduxNodeTwo extends Component {
render(){
return (
<div>
<h6>节点二</h6>
<span>Counter:{this.props.counter}</span>
</div>
)
}
}
const ConnectedReduxNodeTwo = connect(({reducerOne})=>{
return {
counter:reducerOne
}
})(ReduxNodeTwo)
const ConnectedReduxNodeOne= connect(null,{
increment:function(){
return {
type:'reducerOne/INCREMENT'
}
},
decrement:function(){
return {
type:'reducerOne/DECREMENT'
}
}
})(ReduxNodeOne)
export default function(){
return (
<Provider store={store}>
<div>
<h1>Redux Simple Demo</h1>
<ConnectedReduxNodeOne />
<ConnectedReduxNodeTwo/>
</div>
</Provider>
)
};
context
纯react 页面的时候,如果数据的传递要通过多层react 对象的时候,你可以考虑context 传递值哦。
传递方法:
获取值:子组件内定义static contextTypes={ name:PropTypes.string.isRequired, }
在通过this.context 去获取
传递值:父组件定义static childContextTypes={ name:PropTypes.string }
和getChildContext(){ return { name:'爷爷' } }
优点:
- 可以透过多层react 传值
缺点:
- 有点打乱数据传递的流向,不好理解数据
注意事项:
- 一般在写通用性组件的时候才会用到,其他时候尽量用props 或者 redux 去实现
Demo 如下:
import React,{Component} from 'react'
import PropTypes from 'prop-types'
class ContextParent extends Component{
static childContextTypes={
name:PropTypes.string
}
render(){
return (
<div>
Node Parent
{this.props.children}
</div>
)
}
getChildContext(){
return {
name:'爷爷'
}
}
}
class Context extends Component{
render(){
return <div>
Current Node
{this.props.children}
</div>
}
}
class ContextChild extends Component{
static contextTypes={
name:PropTypes.string.isRequired,
}
render(){
return (
<div>
Node Children
<span>Parent:{this.context.name}</span>
</div>
)
}
}
export default function(){
return (
<ContextParent>
<Context>
<ContextChild/>
</Context>
</ContextParent>
)
}
event 传值
通过 eventemitter3 library 实现,也可以用其他的event 库
该传值方案一般作为react state 存储数据时候需要联动触发的业务逻辑以及专业填上线前出现的业务逻辑的代码坑。
传值方式:
获取值:通过在constructor 里面监听event 事件,再setState到内部state
传递值: 触发 emit 事件
优点:
- 事件驱动,可以和其他框架做数据交换
缺点
- 数据流向不明确,不好理解和后续维护
注意事项
- event 的 事件名称 最好是全局的constants 对象,同时也是有规律的
Demo 如下:
import React,{Component} from 'react'
import EventEmitter from 'eventemitter3';
const EVENT = new EventEmitter();
class NodeOne extends Component{
constructor(props){
super(props)
this.state={
counter:0
};
EVENT.on('NodeOne:increment',(num)=>{
this.setState({
counter:this.state.counter+num
})
})
}
render(){
return (
<div>
<h4>Node One 当前counter:{this.state.counter}</h4>
<button onClick={()=>{
EVENT.emit('NodeTwo:increment',20)
}}>Node Two 加 20</button>
</div>
)
}
}
class NodeTwo extends Component{
constructor(props){
super(props)
this.state={
counter:0
};
EVENT.on('NodeTwo:increment',(num)=>{
this.setState({
counter:this.state.counter+num
})
})
}
render(){
return (
<div>
<h4>Node Two当前counter:{this.state.counter}</h4>
<button onClick={()=>{
EVENT.emit('NodeOne:increment',5)
}}>Node One 加 5</button>
</div>
)
}
}
export default function(){
return (
<div>
<NodeOne/>
<NodeTwo/>
</div>
)
}
React 页面间传值的个人总结的更多相关文章
- iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值实现方法:1.通过设置属性,实现页面间传值:2.委托delegate方式:3.通知notification方式:4.block方式:5.UserDefault或者文件方式:6.单例模式 ...
- iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例)
iOS页面间传值的方式(NSUserDefault/Delegate/NSNotification/Block/单例) 实现了以下iOS页面间传值:1.委托delegate方式:2.通知notific ...
- 【转】iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)-- 不错
原文网址:http://www.cnblogs.com/JuneWang/p/3850859.html iOS页面间传值的方式(NSUserDefault/Delegate/NSNotificatio ...
- iOS 页面间传值 之 单例传值 , block 传值
ios 页面间传值有许多,前边已经分享过属性传值和代理传值,今天主要说一下单例传值和 block 传值 单例传值:单例模式一种常用的开发的模式,单例因为在整个程序中无论在何时初始化对象,获取到的都是同 ...
- iOS 页面间传值 之 属性传值,代理传值
手机 APP 运行,不同页面间传值是必不可少,传值的方式有很多(方法传值,属性传值,代理传值,单例传值) ,这里主要总结下属性传值和代理传值. 属性传值:属性传值是最简单,也是最常见的一种传值方式,但 ...
- iOS页面间传值的方式 (Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSN ...
- iOS页面间传值的五种方式总结(Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSNot ...
- mui框架如何实现页面间传值
mui框架如何实现页面间传值 我的传值 listDetail = '<li class="mui-table-view-cell mui-media>">< ...
- MUI框架-02-注意事项-适用场景-实现页面间传值
MUI框架-02-注意事项-适用场景-实现页面间传值 关于开发,我拷贝太多也没什么意义,就请查阅:官方文档:http://dev.dcloud.net.cn/mui/ui/ 快速入门 - 注意事项 有 ...
随机推荐
- 阿里云服务器php环境的搭建
1 sudo apt-get update 更新源 sudo apt-get install apache2##################备注:如果这时候发现无法访问公网ip, 请去配置阿里云后 ...
- 微信小程序---wx.request(OBJECT)
详情 :https://mp.weixin.qq.com/debug/wxadoc/dev/api/network-request.html#wxrequestobject 1: 首先要配置你的域名 ...
- MySQL分区表与合并表
一.分区表 1. 什么是分区表? 对用户来说,分区表是一个独立的逻辑表,但是底层由多个物理子表组成(所以索引也是按照分区的子表定义的, 而没有全局索引).实现分区的代码实际上是对一组底层表的句柄对象的 ...
- KMP (next数组的性质及证明)
性质:如果len%(len-next[len-1])==0,则字符串中必存在最小循环节,且循环次数即为len/(len-next[len-1]); 证明:在前len个字符组成的字符串,存在最小循环节k ...
- Problem C: 线性表的基本操作
Description 线性表是一类重要的且基础的数据结构.请定义MyList类,来模拟针对线性表的插入.删除等操作: 1. 数据成员int *elements:线性表元素. 2. 数据成员int l ...
- 常见的XSS攻击代码
第一类: <tag on*=*/> 在html标签事件中触发,典型的是on*事件,但是这种触发模式的缺陷在于不能直接触发所以更多的需要配合使用. eg: 1.使html元素占据整个显示页面 ...
- ML神器:sklearn的快速使用
传统的机器学习任务从开始到建模的一般流程是:获取数据 -> 数据预处理 -> 训练建模 -> 模型评估 -> 预测,分类.本文我们将依据传统机器学习的流程,看看在每一步流程中都 ...
- 06.十分钟学会表达式语言EL
一. 概念:MVC设计模式一个主要好处就是让jsp中的代码越来越来少,而且规定只能出现三种代码:接收属性,判断语句,迭代输出.但是,在开发中,jsp输出至少还是需要接受VO对象的,这时候为了避免导入V ...
- netty常用使用方式
最近在重新看netty,在这里总结一些netty的一些常用的使用方式,类似于模板,方便速查. 以netty 4.1.x的API作记录,不同版本可能API有略微差异,需要注意netty5被废弃掉了(辨别 ...
- JavaScript 数组基本操作
简介 数组操作无论是在JavaScript中还是在其他语言中都是很常见.经常会用到的,现在我把JavaScript 数组基本操作整理一下,供大家参考学习.里边包含我自己的见解以及案例,希望能够帮助大家 ...