React之使用Context跨组件树传递数据

---------------------------------  讲解一

原文:https://blog.csdn.net/xuxiaoping1989/article/details/78480758

注意: 从 React v15.5 开始 ,React.PropTypes 助手函数已被弃用,我们建议使用 prop-types 库 来定义contextTypes。
2.1首先你需要通过在终端npm install prop-types安装一个叫prop-types的第三方包

getChildContext 定义在父组件中,指定子组件可以使用的信息
childContextTypes 定义在父组件中,getChildContext 指定的传递给子组件的属性需要先通过 childContextTypes 来指定,不然会产生错误
子组件需要通过 contextTypes 指定需要访问的元素。 contextTypes 没有定义, context 将是一个空对象。

父组件定义

class Greeter extends Component{
    constructor(props){
        super(props)
        this.state={
            add:87,
            remove:88
        }
    }
    static childContextTypes = {
        add:T.number,
        remove:T.number
    }
    getChildContext() {
       const { add,remove} = this.state;
       return {
           add,
           remove
       }
    }
    render(){
        return(
            <div>
                <ComponetReflux/>
            </div>
        )
    }
}

子组件定义

class ComponetReflux extends Component{
    constructor(props){
        super(props)
        this.state={

        }
    }
    static contextTypes = {
        add:T.number,
        remove:T.number
    }
    render(){
        console.log(this.context)              //打印{add:87,remove:88}
        const {name,age} = this.state
        return (
            <div>测试context</div>
    )
    }
};

---------------------------------------------------------------  讲解二

原文:https://blog.csdn.net/jimolangyaleng/article/details/77715862

react推崇的是单向数据流,自上而下进行数据的传递,但是由下而上或者不在一条数据流上的组件之间的通信就会变的复杂。解决通信问题的方法很多,如果只是父子级关系,父级可以将一个回调函数当作属性传递给子级,子级可以直接调用函数从而和父级通信。

组件层级嵌套到比较深,可以使用上下文getChildContext来传递信息,这样在不需要将函数一层层往下传,任何一层的子级都可以通过this.context直接访问。

兄弟关系的组件之间无法直接通信,它们只能利用同一层的上级作为中转站。而如果兄弟组件都是最高层的组件,为了能够让它们进行通信,必须在它们外层再套一层组件,这个外层的组件起着保存数据,传递信息的作用,这其实就是redux所做的事情。

组件之间的信息还可以通过全局事件来传递。不同页面可以通过参数传递数据,下个页面可以用location.param来获取。其实react本身很简单,难的在于如何优雅高效的实现组件之间数据的交流。

今天我们就来熟悉下react的context数据传递
 

没有使用Context的情况下传递数据, 我们可以参考React的文档: Context, 它是通过组件属性一级一级往下传递. 这种方式很麻烦, 如果组件树比较深, 必须在每一个路径上的节点都引入不必要的属性.

定义 Context 的根组件

import React      from ‘react‘;

# React 15.5版本以后, 使用PropTypes需要引入外部库, 直接使用React.PropTypes 会抛警告
import PropTypes from ‘prop-types‘;

# React Router V4版本要从 react-router-dom 导入需要的组件
import { Route, Link } from ‘react-router-dom‘;

import { Row, Col, Menu, Icon, Dropdown, Layout} from ‘antd‘;
const { Sider, Content } = Layout;

import UserList   from ‘./UserList‘;
import UserDetail from ‘./UserDetail‘;
import Sidebar    from ‘../_layouts/Sidebar‘;

const avatars = [
  "elyse.png",
  "kristy.png",
  "matthew.png",
];

const data = [];
for(let i = 0; i <= avatars.length; i++){
  data.push({key: i, name: ‘胡彦祖3‘,age: 42,address: ‘西湖区湖底公园1号‘});
}
const columns = [
  { title: ‘ID‘,dataIndex: ‘key‘,key: ‘key‘},
  { title: ‘姓名‘,dataIndex: ‘name‘,key: ‘name‘, render: function(text, record, index) {
    return (<Link to={`/users/${index}`}><div style={{display: ‘block‘}}>{text}</div></Link>)
  }},
  { title: ‘年龄‘,dataIndex: ‘age‘,key: ‘age‘},
  { title: ‘住址‘,dataIndex: ‘address‘,key: ‘address‘},
  {
    title: ‘Action‘,
    key: ‘action‘,
    render: function(text, record, index){
      return (
        <span>
          <a><Icon type="plus" /></a>
          <span className="ant-divider" />
          <a><Icon type="close" /></a>
        </span>
      )
    }
  }
];

class UserIndex extends React.Component {
  constructor(props){
    super(props)
  }

  # 定义Context需要实现的方法

  getChildContext() {
    return {
      data: data,
      columns: columns
    };
  }
  render(){
    return (
      <Layout>
        <Sider>
          <div id="user-side-bar" className="side-bar">
          <Sidebar/>
          </div>
        </Sider>
        <Content>
          <h2 className="pagetitle">用户信息页</h2>
          <Row gutter={16}>
            <Col span={16}>
              <UserList />
            </Col>
            <Col span={4}>
              <Route path={`${this.props.match.url}/:id`} component={UserDetail}/>
            </Col>
          </Row>
        </Content>
      </Layout>
    )
  }
}

# 声明Context类型

UserIndex.childContextTypes = {
  data: PropTypes.array,
  columns: PropTypes.array,
};

export default UserIndex;

中间组件

中间中间不再通过组件属性一级一级的往下传递了. 我们这里在 render() 函数中定义一个空的 <List/>:

import { Table, Icon } from ‘antd‘;

import {
  Link
} from ‘react-router-dom‘;

import List from ‘../_common/List‘;

class UserList extends React.Component {
  constructor(props){
    super(props)
  }
  render(){
    return (
      <div>
        <List />
      </div>
    )
  }
}

export default UserList;

子组件, 列表

import React from ‘react‘;
import PropTypes from ‘prop-types‘;
import { Layout, Table } from ‘antd‘;
const { Sider, Content } = Layout;
class List extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Content>
        <Table columns={this.context.columns} dataSource={this.context.data} size="middle" />
      </Content>
    );
  }
}

List.propTypes = {
    data: PropTypes.array,
    columns: PropTypes.array
};

# 在这里声明 contextTypes 用于访问 UserIndex 组件中定义的Context数据.

List.contextTypes = {
  data: PropTypes.array,
  columns: PropTypes.array
};

export default List;

这样我们就可以在子组件中获取到父组件的数据了,不管多少层都能获取到。

原文地址:https://www.cnblogs.com/wind-wang/p/9857790.html

时间: 2024-07-28 23:17:20

React之使用Context跨组件树传递数据的相关文章

组件之间传递数据。 flutter中在Stepper中传递数据

A是一个有状态的组件 可以在构造函数里传递数据 myData可以是一个对象类型的引用.那么把引用传过来.便可以在组件里修改他的属性了. 如果是外部调用A组件,那么只需要在构造A组件的时候传递自定义的参数即可. A(myData:mydata); class MyData{ String name; } // ----------------- class A extends StatefulWidget { MyData myData; A({this.myData}) @override _A

vue.js 组件之间传递数据

组件是 vue.js  最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.如何传递数据也成了组件的重要知识点之一.本文就这个知识点和大家一起来扒一扒,希望对大家 学习vue.js有所帮助. 组件 组件与组件之间,还存在着不同的关系.父子关系与兄弟关系(不是父子的都暂称为兄弟吧). 父子组件 父子关系即是组件 A  在它的模板中使用了组件  B ,那么组件  A  就是父组件,组件  B  就是子组件. //  注册一个子组件 Vue.component(

Spring 跨重定向请求传递数据

在处理完POST请求后, 通常来讲一个最佳实践就是执行一下重定向.除了其他的一些因素外,这样做能够防止用户点击浏览器的刷新按钮或后退箭头时,客户端重新执行危险的POST请求. 在控制器方法返回的视图名称中,我们借助了" redirect:" 前缀的力量.当控制器方法返回的String 值 以" redirect:" 开头 的 话, 那么 这个 String 不是 用来 查找 视图 的, 而是 用来 指导 浏览器 进行 重定向 的 路径. 我们 可以 回头 看一下 程

SpringMVC跨重定向请求传递数据

(1)使用URL模板以路径变量和查询参数的形式传递数据(一些简单的数据) 1 @GetMapping("/home/index") 2 public String index(Model model){ 3 Meinv meinv = new Meinv("gaoxing",22); 4 model.addAttribute("lastName",meinv.getLastName()); 5 model.addAttribute("a

Spring之跨重定向请求传递数据

摘要 在开发场景中,大部分数据都是使用请求转发(forward)进行传递,而使用重定向(redirect)传递数据可能比较少. 那么问题来了:请求中的数据生命周期存活时间只在一个请求转发(request)中,当这个请求结束后,那么请求中所带的数据也会随着这个请求一起拜拜了.而重定向会向服务器发起两个请求,所以第一个请求的数据不就到不了第二个请求了吗?如图: 如果我们想传递的数据在第二个请求中有效,那么怎么办呢? 有以下两种方法可以解决: url路径传递 使用flash属性 url路径传递 url

React 借助pubsub-js进行兄弟组件的传递值

1===> raect中两个 兄弟组件 互相通信使用的技术 使用 消息订阅(subscribe)和发布(publish)机制 s儿 伯 s rai b p? b l? ? 有一个库可以处理 PubSubJS 它是第三方插件 1)下载 cnpm install pubsub-js -S 我的版本 "pubsub-js": "^1.7.0", 2) 在需要使用的组件中引入 import PubSub from "pubsub-js" // id

Spring 梳理-跨重定向请求传递数据-Flash

Spring MVC Flash Attribute 的讲解与使用示例 1. Spring MVC 3.1版本加了一个很有用的特性,Flash属性,它能解决一个长久以来缺少解决的问题,一个POST/Redirect/GET模式问题. 正常的MVC Web应用程序在每次提交都会POST数据到服务器.一个正常的Controller (被注解 @Controller标记)从请求获取数据和处理它 (保存或更新数据库).一旦操作成功,用户就会被带到(forward)一个操作成功的页面.传统上来说,这样的P

vue组件父子组件之间传递数据

举个栗子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../Vue.js"></script> <template id="tpl1"> <h3>我是父组件

Intent之使用Extra属性在组件之间传递数据

第一步: 在MainActivity中使用Intent封装数据并传到第二个Activity package com.example.intent; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.view.View.OnClickListen