1. props属性

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

2. Context传值

1. 应用场景

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

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

2. 使用方法

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

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

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

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

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

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

3. 使用Consumer获取数据

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

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

  1. static contextType = ThemeContext;
  2. render() {
  3. return (
  4. <div style={{background: this.context.theme.backgroundColor}}>
  5. <button onClick={this.context.changeTheme}>切换主题</button>
  6. </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调用子组件的实例方法

  1. class App extends React.Component {
  2. constructor(props) {
  3. super(props);
  4. this.ref = React.createRef();
  5. }
  6. componnetDidMount() {
  7. // this.ref.current指向子组件的实例对象this
  8. this.ref.current.resetData()
  9. }
  10. render() {
  11. // 只能是类子组件
  12. return <Child ref={this.ref}>
  13. }
  14. }
  15.  
  16. class Child extends React.Component {
  17. resetData = () => {
  18. // TODO
  19. }
  20. render() {
  21. return <div></div>
  22. }
  23. }

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

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

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

  1. function CustomTextInput(props) {
  2. // 这里必须声明 textInput,这样 ref 才可以引用它
  3. let textInput = React.createRef();
  4. function handleClick() {
  5. textInput.current.focus();
  6. }
  7. return (
  8. <div>
  9. <input
  10. type="text"
  11. ref={textInput} />
  12. <input
  13. type="button"
  14. value="Focus the text input"
  15. onClick={handleClick}
  16. />
  17. </div>
  18. );
  19. }

3. Refs转发方法

1. 非高阶组件转发

  1. class App extends React.Component{
  2. constructor(props) {
  3. super(props);
  4. this.ref = React.createRef(); //初始化一个变量
  5. }
  6. componentDidMount() {
  7. console.log(this.ref.current); // <div id="toolbar">Toolbar</div>
  8. }
  9. render() {
  10. return (
  11. <div>
  12. <Toolbar ref={this.ref} />
  13. <div>App</div>
  14. </div>
  15. )
  16. }
  17. }
  18. // 传递到子组件后给其赋值
  19. const Toolbar = React.forwardRef((props, ref) => (
  20. <div ref={ref} id="toolbar">
  21. Toolbar
  22. </div>
  23. ));

2. 高阶组件转发refs

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

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

  1. // 高阶组件代码
  2. function logProps(WrappedComponent) {
  3. class LogProps extends React.Component {
  4. componentDidUpdate(prevProps, prevState, snapshot) {
  5. console.log('prevProps-->',prevProps)
  6. console.log('this.props-->',this.props)
  7. }
  8. render() {
  9. const {forwardRef, ...rest} = this.props;
  10. // ref指向被包裹的组件
  11. return <WrappedComponent {...rest} ref={forwardRef} />
  12. }
  13. }
  14. return React.forwardRef((props, ref) => {
  15. return <LogProps {...props} forwardRef={ref} />
  16. });
  17. }
  18. export default logProps;
  19.  
  20. // 被包裹组件代码
  21. import React from 'react';
  22. import logProps from './logProps';
  23. class Toolbar extends React.Component {
  24. render() {
  25. return (
  26. <div>Toolbar</div>
  27. )
  28. }
  29. }
  30. export default logProps(Toolbar)
  31.  
  32. // 父组件代码
  33. import Toolbar from './toolbar';
  34.  
  35. class App extends React.Component{
  36. constructor(props) {
  37. super(props);
  38. this.ref = React.createRef();
  39. this.state = {num: 1}
  40. }
  41. componentDidMount() {
  42. console.log(this.ref.current); //Toolbar
  43. }
  44. add = () => {
  45. this.setState(state => ({
  46. num: state.num + 1
  47. }))
  48. }
  49. render() {
  50. return (
  51. <div>
  52. <Toolbar ref={this.ref} />
  53. <div onClick={this.add}>{this.state.num}</div>
  54. </div>
  55. )
  56. }
  57. }

4. 回调函数Refs

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

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

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

  1. function FunComponent(props) {
  2. return <div ref={props.funRef}>函数组件</div>
  3. }
  4. class App extends React.Component {
  5. componentDidMount() {
  6. // 获取到函数子组件的DOM节点
  7. console.log(this.ref); //<div>函数组件</div>
  8. }
  9. render() {
  10. return(
  11. <FunComponent funRef={(element) => {this.ref = element}} />
  12. )
  13. }
  14. }

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. linux终端提示符修改

    Linux主机名莫名其妙的由@myhostname变成了@bogon了之后 1.在linux下添加一个127.0.0.2名叫bogon的主机此方法使用后,bogon主机名得以解析,使用的主机名仍为bo ...

  2. Comet OJ Contest 4

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 ...

  3. 安装CentOS7服务器

    1. 基本安装 https://www.cnblogs.com/kreo/p/4396825.html 2.安装补充 防火墙 / FTP / Nginx https://www.cnblogs.com ...

  4. .netCore 简易Web 项目

    static async Task Main(string[] args) { var _httpListener = new HttpListener(); _httpListener.Prefix ...

  5. Django2.0 分页的应用

    #分页例子from django.core.paginator import Paginatordef blog_list(request):      blog_all_list = models. ...

  6. 3.Ubuntu/Deepin下安装Monaco/Menlo字体

    前段时间在一家公司实习,让IT给电脑安装了Ubuntu系统,用着挺好,但总感觉字体不太好看,网上小伙伴说Monaco字体不错,所以计划安装试试. 看了好多教程,不得不说,一些教程走下来真心是装不成功, ...

  7. 移动端调试工具Vconsole

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. MySQL 启动、登录、退出和目录结构

    一.启动 MySQL 服务器启动方式有两种: (1)通过服务的方式自动启动 (2)手动启动的方式 1.windows 服务方式启动 操作步骤: 也可以在 cmd 窗口 输入 services.msc ...

  9. springboot问题排解

    1.SpringBoot 升级到 2.1.5.RELEASE 以上后 pom.xml 报 Unknown错误 1.SpringBoot 升级到 2.1.5.RELEASE 以上后 pom.xml 报 ...

  10. C#-FileHelper

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...