React之使用Context跨組件樹傳遞資料

來源:互聯網
上載者:User

標籤:extends   rop   ofo   outer   pes   lis   方式   type   OLE   

---------------------------------  講解一 

原文:78480758 

 

注意: 從 React v15.5 開始 ,React.PropTypes 助手函數已被棄用,我們建議使用 prop-types 庫 來定義contextTypes。
2.1首先你需要通過在終端npm install prop-types安裝一個叫prop-types的第三方包

getChildContext 定義在父組件中,指定子組件可以使用的資訊
childContextTypes 定義在父組件中,getChildContext 指定的傳遞給子組件的屬性需要先通過 childContextTypes 來指定,不然會產生錯誤
子組件需要通過 contextTypes 指定需要訪問的元素。 contextTypes 沒有定義, context 將是一個Null 物件。

父組件定義 

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>    )    }};

 

 

---------------------------------------------------------------  講解二 

原文: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;

 

這樣我們就可以在子組件中擷取到父組件的資料了,不管多少層都能擷取到。

 

React之使用Context跨組件樹傳遞資料

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.