繁体   English   中英

在ReactJS中使用ref值调用函数会引发错误

[英]calling a function using ref value in ReactJS throws error

我正在学习ReactJS,并且编写了一个简单的程序,其中一些记录显示在列表中,并且可以通过单击其删除按钮来删除每个记录。 我的代码中包含三个组件。 Store正在调用View组件以显示记录,而View正在调用Action组件以删除任何记录。

现在的问题是,当我按Delete按钮删除任何记录时,我收到了Uncaught TypeError: Cannot read property 'deleteRecord' of undefined错误的Uncaught TypeError: Cannot read property 'deleteRecord' of undefined 因此,请告诉我代码中的问题是什么?

错误:

Uncaught TypeError: Cannot read property 'deleteRecord' of undefined
    at onClick (index.js:32647)
    at Object.ReactErrorUtils.invokeGuardedCallback (index.js:7735)
    at executeDispatch (index.js:7519)
    at Object.executeDispatchesInOrder (index.js:7542)
    at executeDispatchesAndRelease (index.js:5512)
    at executeDispatchesAndReleaseTopLevel (index.js:5523)
    at Array.forEach (<anonymous>)
    at forEachAccumulated (index.js:11731)
    at Object.processEventQueue (index.js:5723)
    at runEventQueueInBatch (index.js:26646)

码:

index.html

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "UTF-8">
    <title>React App</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
    <div id = "app"></div>
    <script src = "index.js"></script>
</body>
</html>

main.js

import React from 'react';
import ReactDOM from 'react-dom';
import Store from './Store.jsx';

ReactDOM.render(
    <Store />,
    document.getElementById('app')
);

Store.jsx

import React from 'react';
import View from './View.jsx';

class Store extends React.Component {

    constructor() {
        super();

        this.state = {
            records: [
                {
                    id: 1,
                    name: 'First User',
                },
                {
                    id: 2,
                    name: 'Second User',
                },
                {
                    id: 3,
                    name: 'Third User'
                }
            ]
        }

        this.updateStore = this.updateStore.bind(this);
    };

    updateStore(newState) {
        this.setState({records: newState});
    };

    render() {
        return (
            <div>
                <View store={this.state.records} updateStore={this.updateStore} />
            </div>
        );
    }
};

export default Store;

View.jsx

import React from 'react';
import Action from './Action.jsx';

class View extends React.Component {
    render() {
        return (
            <div className="container">
                <ul className="list-group">
                    {this.props.store.map((eachRecord,index) =>
                        <ListItem key={index} actionHandler={this.refs.actionHandler} singleRecord={eachRecord} />
                    )}
                </ul>
                <Action ref="actionHandler" store={this.props.store} updateStore={this.props.updateStore} />
            </div>
        );
    }
}

class ListItem extends React.Component {
    render() {
        return (
            <li className="list-group-item">
                {this.props.singleRecord.name}
                <button style={{float:'right'}} onClick={() => this.props.actionHandler.deleteRecord(this.props.singleRecord)}>Delete</button>
            </li>
        );
    }
}

export default View;

Action.jsx

import React from 'react';

class Action extends React.Component {
    render() {
        return (
            <div></div>
        );
    };

    deleteRecord(record) {
        var newStore = this.props.store.filter(eachR => eachR !== record);
        this.props.updateStore(newStore);
    }
}

export default Action;

您正在使用refs对象,然后对组件的ref进行附加反应。 它的被推荐的反应以不使用refs这样的了,而是使用ref与回调: <div ref={ref => this.divRef = ref} /> https://facebook.github.io/react/docs/refs -and-the-dom.html

但是在您的情况下,只需将回调传递给组件即可,而完全不使用refs 首先,似乎<Actions />组件是不必要的。 您可以将回调函数传递给<ListItem />组件:

class ListItem extends React.Component {

  deleteRecord(record) {
    var newStore = this.props.store.filter(eachR => eachR !== record);
    this.props.updateStore(newStore);
  }

  render() {
    return (
      <li className="list-group-item">
        {this.props.singleRecord.name}
        <button style={{ float: 'right' }} onClick={() => this.deleteRecord(this.props.singleRecord)}>Delete</button>
      </li>
    );
  }
}

现在,当您单击此按钮时,此组件将知道该怎么办。

请注意,现在您需要将所有这些道具传递给<ListItem />组件,如下所示:

<ListItem key={index} store={this.props.store} updateStore={this.props.updateStore} singleRecord={eachRecord} />

为了获得更好的方法并减少传递的道具,您可能希望将deleteRecord函数放在顶层组件上,而仅向下传递该组件。 关于它的更多信息,您可以在这里阅读: https : //facebook.github.io/react/docs/lifting-state-up.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM