1. props属性

典型的React应用,数据通过props按照自上而下(父->子)的顺序传递数据。

2. Context传值

1. 应用场景

对于一些应用中全局性的属性(如UI主题、语言、登陆用户等),通过props传递会很繁琐。

Context的出现可以在组件之间(父->子)共享这些属性。

2. 使用方法

1. 创建Context对象(写入一个单独的文件)

const ThemeContext = React.createContext(defaultValue)
const ThemeContext = React.createContext({
theme: themes.dark,
changeTheme: () => {}
});

2. 使用Provider提供数据,数据可以是原始类型,也可以是对象;

可以是常量也可以是变量;

注意: 如果是对象,通过state值传入,否则每次渲染都是新的对象。

      <ThemeContext.Provider value={this.state}>
<Toolbar />
</ThemeContext.Provider>

3. 使用Consumer获取数据

      <ThemeContext.Consumer>
{({theme, changeTheme}) => <div style={{background: theme.backgroundColor}}>
<button onClick={changeTheme}>切换主题</button>
</div>}
</ThemeContext.Consumer>

4. 也可以通过赋值静态属性contextType后,通过this.context获取值

  static contextType = ThemeContext;
render() {
return (
<div style={{background: this.context.theme.backgroundColor}}>
<button onClick={this.context.changeTheme}>切换主题</button>
</div>

3. createRef API生成的Refs(React V16.3+)

将ref自动的通过组件传递到子组件。然后通过ref获取子组件的DOM。

1. Refs应用场景

1. 对于那些高可复用的,诸如<Button><SelectInput>等“叶”组件,经常会需要获取

DOM节点,实现管理焦点、文本选择、播放动画等。

2. 对于触发强制动画。

3.对于集成第三方DOM库。

注意: 高级组件不能通过属性转发ref

2. 访问ref的current属性

1. 对于HTML元素,current属性指向底层的DOM元素。

2.对于class组件元素,current属性指向组件的实例对象(即this)。

这样可以在父组件中,通过this.ref.current调用子组件的实例方法

class App extends React.Component {
constructor(props) {
super(props);
this.ref = React.createRef();
}
componnetDidMount() {
// this.ref.current指向子组件的实例对象this
this.ref.current.resetData()
}
render() {
// 只能是类子组件
return <Child ref={this.ref}>
}
} class Child extends React.Component {
resetData = () => {
// TODO
}
render() {
return <div></div>
}
}

3. 不能在函数组件上使用ref,因为它没有实例。

function FunComponent(props) {
return <div></div>
}
// 错误!函数组件上不能使用ref属性
<FunComponent ref={this.myref}/>

但是可以在函数组件内部使用,只要它指向DOM或者类组件。

function CustomTextInput(props) {
// 这里必须声明 textInput,这样 ref 才可以引用它
let textInput = React.createRef();
function handleClick() {
textInput.current.focus();
}
return (
<div>
<input
type="text"
ref={textInput} />
<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}

3. Refs转发方法

1. 非高阶组件转发

class App extends React.Component{
constructor(props) {
super(props);
this.ref = React.createRef(); //初始化一个变量
}
componentDidMount() {
console.log(this.ref.current); // <div id="toolbar">Toolbar</div>
}
render() {
return (
<div>
<Toolbar ref={this.ref} />
<div>App</div>
</div>
)
}
}
// 传递到子组件后给其赋值
const Toolbar = React.forwardRef((props, ref) => (
<div ref={ref} id="toolbar">
Toolbar
</div>
));

2. 高阶组件转发refs

当使用{...this.props}进行透传时,因为ref不是属性,所以不能通过其透传。

但是可以在高阶组件内部,通过React.forwardRef()进行转发。

// 高阶组件代码
function logProps(WrappedComponent) {
class LogProps extends React.Component {
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('prevProps-->',prevProps)
console.log('this.props-->',this.props)
}
render() {
const {forwardRef, ...rest} = this.props;
// ref指向被包裹的组件
return <WrappedComponent {...rest} ref={forwardRef} />
}
}
return React.forwardRef((props, ref) => {
return <LogProps {...props} forwardRef={ref} />
});
}
export default logProps; // 被包裹组件代码
import React from 'react';
import logProps from './logProps';
class Toolbar extends React.Component {
render() {
return (
<div>Toolbar</div>
)
}
}
export default logProps(Toolbar) // 父组件代码
import Toolbar from './toolbar'; class App extends React.Component{
constructor(props) {
super(props);
this.ref = React.createRef();
this.state = {num: 1}
}
componentDidMount() {
console.log(this.ref.current); //Toolbar
}
add = () => {
this.setState(state => ({
num: state.num + 1
}))
}
render() {
return (
<div>
<Toolbar ref={this.ref} />
<div onClick={this.add}>{this.state.num}</div>
</div>
)
}
}

4. 回调函数Refs

ref还可以接收一个回调函数,作为ref的属性内容。

<div ref={(element) => this.ref = element}></div>

使用回调函数也ref可以获取子组件的DOM节点。

function FunComponent(props) {
return <div ref={props.funRef}>函数组件</div>
}
class App extends React.Component {
componentDidMount() {
// 获取到函数子组件的DOM节点
console.log(this.ref); //<div>函数组件</div>
}
render() {
return(
<FunComponent funRef={(element) => {this.ref = element}} />
)
}
}

React应用数据传递的方式的更多相关文章

  1. ios应用view之间数据传递的方式

    对于不同的viewcontroller之间数据的共享和处理 采用代理的方式,子viewcontroller设计代理协议,并定义协议接口,父viewcontroller实现协议接口,实现子视图控制器退出 ...

  2. react渲染数据3种方式

    直接渲染,()类似于模板字符串,包裹一个dom元素 ReactDOM.render( (<div> <h2>现在时间:{new Date().toLocaleTimeStrin ...

  3. MVC中Control和View之间数据传递的方式

    1:ViewBag和ViewData 具体区别不做讨论,本处只演示ViewData的具体示例: Controler代码:ViewData["Employee"] = emp; Vi ...

  4. React中父组件与子组件之间的数据传递和标准化的思考

    React中父组件与子组件之间的数据传递的的实现大家都可以轻易做到,但对比很多人的实现方法,总是会有或多或少的差异.在一个团队中,这种实现的差异体现了每个人各自的理解的不同,但是反过来思考,一个团队用 ...

  5. react生命周期,中间件、性能优化、数据传递、mixin的使用

    https://github.com/lulujianglab/blog/issues/34 一.生命周期 1,初始化的执行顺序,初始生命周期执行过程详解 class initSate extends ...

  6. Android数据传递,使用广播BroadcastReceiver;

    Android数据传递有很多种,Intent意图传递或使用Bundle去传递,接口监听回调传递数据,也可以把数据保存起来,使用的时候去读取等等等...,"当你知道足够多的数据传递的方式之后, ...

  7. React Native移动开发实战-3-实现页面间的数据传递

    React Native使用props来实现页面间数据传递和通信.在React Native中,有两种方式可以存储和传递数据:props(属性)以及state(状态),其中: props通常是在父组件 ...

  8. React学习(2)—— 组件的运用和数据传递

    React官方中文文档地址:    https://doc.react-china.org/ 了解了组件之后,就需要理解“Props”和“State”的用法.首先来介绍State,State按照字面意 ...

  9. react之组件数据挂在方式

    1.属性(props) 组件间传值,在React中是通过只读属性 props 来完成数据传递的. props:接受任意的入参,并返回用于描述页面展示内容的 React 元素. import React ...

随机推荐

  1. PAT(B) 1051 复数乘法(Java)

    题目链接:1051 复数乘法 (15 point(s)) 参考博客:1051 复数乘法(PAT 乙级 C++实现)-guangjinzheng 题目描述 复数可以写成 (A+Bi) 的常规形式,其中 ...

  2. Eclipse RCP难点:给Command传递参数(Object)

    这个问题网络上没有答案,国外网站上也没有,本人研究了一天,终于搞明白如何实现,实际上是Eclipse RCP的ICommandService本身就已经提供的方法,只是网络上教的都是使用IHandler ...

  3. apply,call和bind的使用及区别

    1.用途 1)apply,call和bind都是 用来改变this的指向 2)apply和call会让当前函数立即执行,而bind会返回一个函数,后续需要的时候再调用执行 2.this指向问题 thi ...

  4. windows + Eclipse 汉化

    https://www.eclipse.org/babel/downloads.php 下载Eclipse 对应版本 汉化包解压 复制文件夹里的内容到eclipse 文件夹下对应的文件里 重启ecli ...

  5. .net mvc 迁移到 .netcore

    迁移的时候发现,ef6 不能添加 到  .NET Standard2  的类库,因为不兼容, 6 以上的版本只能用于  .net 4.5 以上 只能用别的

  6. VBA循环(十一)

    当需要多次执行一段代码时,就可以使用循环语句. 一般来说,语句是按顺序执行的:函数中的第一个语句首先执行,然后是第二个,依此类推. 编程语言提供了各种控制结构,允许更复杂的执行路径. 循环语句允许多次 ...

  7. Ubuntu下编译 Hadoop2.9

    Ubuntu 下编译 Hadoop-2.9.2 系统环境 系统: ubuntu-18.10-desktop-amd64 maven: Apache Maven 3.6.0 jdk: jdk_1.8.0 ...

  8. ES6中 对字符串增强

    在曾经,我们只能用A.indexof(B)来判断A中是否含有B字符串: 现在在ES6中 有了: includes(), startswith(),endswith() reapt()重复次数: 输出 ...

  9. webpack4 + ejs 构建多页应用

    目录结构 ├─build webpack配置目录 │ ├─plugins.js │ ├─rules.js │ ├─transfromAssets.js //简单的一个插件,处理路径问题 │ └─web ...

  10. 第七周作业:powerdesigner使用小结

    powerdesigner使用小结 这款软件使得开发人员为了方便进行数据库的建立以及逻辑关系的实现,而不用自己去“手写”代码,代码在数据库建模完成后可以直接的生成. 如果你电脑上安装了这款软件的话可以 ...