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/ 快速入门 - 注意事项 有 ...
随机推荐
- 有序链表--Java实现
/*有序链表--使用的是单链表实现 *在插入的时候保持按照值顺序排列 *对于删除最小值的节点效率最高--适合频繁的删除最小的节点 * */ public class MySortedLinkList ...
- 【20171026早】alert(1) to win - 第六、七、八题
早上7点起床,又写了一篇小说发在了起点网上,有兴趣的可以看看.点击这里 忙完后,继续练习,刚开始发现自己答题的速度有些慢,可能是因为对于html,javascript知识不是很精通,但是话又说回来,谁 ...
- .5-Vue源码之AST(1)
讲完了数据劫持原理和一堆初始化 现在是DOM相关的代码了 上一节是从这个函数开始的: // Line-3924 Vue.prototype._init = function(options) { // ...
- Redhat Linux 自动修改密码
bash下使用echo+passwd命令修改密码的方法.方法一:echo "Password" |passwd username --stdin方法二:(echo "Pa ...
- VS2012环境下C#调用C++生成的DLL
1.VS2012 C++生成DLL 这个过程仿照http://www.cnblogs.com/LCCRNblog/p/3625200.html创建DLL即可,暂时不用创建测试工程,因为下面有测试工程的 ...
- n! 进制
n! 进制 Time limit per test: 1.0 seconds Time limit all tests: 1.0 seconds Memory limit: 256 megabytes ...
- 图片验证码的JAVA工具类
我们平时开发时经常会遇到需要图片验证码,基础的验证码包括了数字.字母.甚至可能有汉字.下面我给出一个简单的工具类. package com..ankang.tony.util; import java ...
- jQuery+ajax实现局部刷新
在项目中,经常会用到ajax,比如实现局部刷新,比如需要前后端交互等,这里呢分享局部刷新的两种方法,主要用的是ajax里面的.load(),其他高级方法的使用以后再做详细笔记. 第一种: 当某几个页面 ...
- C# 4.0 新特性dynamic、可选参数、命名参数等
1.dynamic ExpandoObject熟悉js的朋友都知道js可以这么写 : 1 var t = new Object(); 2 t.Abc = ‘something’; 3 t.Valu ...
- 利用C#实现分布式数据库查询
随着传统的数据库.计算机网络和数字通信技术的飞速发展,以数据分布存储和分布处理为主要特征的分布式数据库系统的研究和开发越来越受到人们的关注.但由于其开发较为复杂,在一定程度上制约了它的发展.基于此,本 ...