如何访问this.context.router (ReactJS)

How to access this.context.router (ReactJS)

本文关键字:ReactJS context router this 访问 何访问      更新时间:2023-09-26

这是我的代码:

import React from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table'
import sampleSystems from '../sample-systems';
class SystemTable extends React.Component {
constructor() {
    super();
    this.state = {
        data: sampleSystems
    }
}
render() {
    function osName(cell, row) {
      return cell.name;
    }
    function batteryCondition(cell, row) {
      return cell.condition;
    }
    var selectRowProp = {
      mode: "checkbox", 
      bgColor: "rgb(204, 230, 255)"
    };  
    var tableOptions = {
        sizePerPage: 5,
        deleteText: "✗ Delete Selected",
        paginationSize: 3,
        clearSearch: true,
        hideSizePerPage: true,
        onRowClick: function(row) {
            const systemId = row._id;
            this.context.router.transitionTo(`/system/${systemId}`);
        }
};
    return (
        <BootstrapTable 
            className="react-bs-table"
            data={this.state.data.systems}
            striped={true}
            hover={true}
            pagination={true}
            selectRow={selectRowProp}
            deleteRow={true}
            multiColumnSearch={true}
            search={true}
            ignoreSinglePage={true}
            options={tableOptions}
            >
          <TableHeaderColumn dataField="_id" isKey={true} dataAlign="center" 
            searchable={false}>ID</TableHeaderColumn>
          <TableHeaderColumn dataField="serialnumber" dataAlign="center"
            searchable={false}>Serial Number</TableHeaderColumn>
          <TableHeaderColumn dataField="model" dataAlign="center" 
            dataSort={true}>Model</TableHeaderColumn>
            <TableHeaderColumn dataField="os" dataAlign="center" dataSort={true} 
                dataFormat={osName} filterValue={osName}>OS</TableHeaderColumn>
            <TableHeaderColumn dataField="battery" dataAlign="center" dataSort={true} 
                dataFormat={batteryCondition} filterValue={batteryCondition}>
                Battery Condition</TableHeaderColumn>
        </BootstrapTable>
    )
    }
}
SystemTable.contextTypes = {
    router: React.PropTypes.object
}
export default SystemTable;

我希望能够在渲染方法的tableOptions变量中访问this.context.router,在onRowClick属性中。每当我尝试以这种方式访问它时,我得到Uncaught TypeError: Cannot read property 'router' of undefined,有人能帮我解决这个问题吗?谢谢!

编辑

SystemTable组件是在App组件内部使用的,我应该在这里初始化withouter或browserHistory吗?
<BrowserRouter>
    <div>
        <Match exactly pattern="/" component={App} />
        <Match pattern="/system/:systemId" component={SystemInfo} />
        <Miss component={NotFound} />
    </div>
</BrowserRouter>

您的问题是您在function中使用this.context,在您的情况下,将导致this成为您的tableOptions对象,而不是组件类。

有几种方法可以解决这个问题:

1)创建函数

时绑定this
var tableOptions = {
    /* ... */
    onRowClick: function(row) {
        const systemId = row._id;
        this.context.router.transitionTo(`/system/${systemId}`);
    }.bind(this)
};

2)在变量

中存储this
var _this = this;
var tableOptions = {
    /* ... */
    onRowClick: function(row) {
        const systemId = row._id;
        _this.context.router.transitionTo(`/system/${systemId}`);
    }
};
3)使用ES6箭头功能
var tableOptions = {
    /* ... */
    onRowClick: row => {
        const systemId = row._id;
        this.context.router.transitionTo(`/system/${systemId}`);
    }
};

您可以在MDN上阅读更多关于this的信息,例如

当您想要使用React组件的context属性时,您必须声明它们的类型,就像prop验证一样。在您的情况下,使用ES6类,它是这样做的:

static contextTypes = {
    router: React.PropTypes.object
}

尽管如此,考虑升级路由器,正如评论中指出的那样,因为看起来你使用的是旧版本。它可能工作得很好,但是其中一些功能不稳定,将来可能会崩溃。

额外提示:你似乎使用了很棒的ES6功能和语法(做得好!)所以考虑不再使用var,而是切换到let

这是一个小细节,可以为您省去一些麻烦。

要访问更深层次的路由器,你可以使用withouter

withRouter(YourComponent)

它将有this.props.router

或者你可以直接使用浏览器历史记录导航。

请注意,在路由中直接引用的组件将已经具有this.props.router

请注意,你没有提到你使用的是什么版本,这是最新的