Невозможно вызвать метод вне рендеринга из функции внутри рендеринга

class TableView extends React.Component {  
    state = {
        open: false,
    };

    onOpenModal = () => {
        this.setState({ open: true });
    };

    onCloseModal = () => {
        this.setState({ open: false });
    };

    render() {
        function showHistory() {
            this.onOpenModal; // not able to do this
            console.info(this.state.open); // or this
        }
        return (
             //...
             //...
            <Modal open = {this.state.open} onClose = {this.onCloseModal} center>
                <h2>History</h2>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                    pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet
                    hendrerit risus, sed porttitor quam.
                </p>
            </Modal>
       );
   }
}

Я могу нажать метод showHistory одним нажатием кнопки внутри jsx. Но когда я пытаюсь вызвать onOpenModal из showHistory, он выдает ошибку -

Uncaught TypeError: Cannot read property 'onOpenModal' of undefined

Как мне вызвать onOpenModal из showhistory?

это означает, что у вас этого нет в наличии. Вместо этого используйте функцию стрелки внутри рендера

Shubham Agarwal Bhewanewala 03.08.2018 09:01

почему вы добавляете эту функцию в рендер? это не обычное место для функций в React

Pixelomo 03.08.2018 09:17
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
2
884
4

Ответы 4

попробуйте это, вам может понадобиться скобка

this.onOpenModal()

в противном случае переместить функцию за пределы рендеринга

class TableView extends React.Component {  
    state = {
        open: false,
    };

    onOpenModal = () => {
        this.setState({ open: true });
    };

    onCloseModal = () => {
        this.setState({ open: false });
    };

    showHistory() {
        () => this.onOpenModal() // not able to do this
        console.info(this.state.open); // or this
    }

    render() {
        return (
             //...
             //...
            <Modal open = {this.state.open} onClose = {this.onCloseModal} center>
                <h2>History</h2>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                    pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet
                    hendrerit risus, sed porttitor quam.
                </p>
            </Modal>
       );
     }
   }

возможно, вам нужно привязать this, самый простой способ сделать это - использовать функции жирных стрелок

() => this.onOpenModal()

даже жирная стрелка?

Pixelomo 03.08.2018 09:06

после добавления толстой стрелки это не дало никаких ошибок, но и не попало в onOpenModal ().

Shubham 03.08.2018 09:17

вы переместили функцию за пределы рендера?

Pixelomo 03.08.2018 09:18

Во-первых, вы не вызываете onOpenModal, вам не хватает скобок: this.onOpenModal(), во-вторых, вам нужно связать showHistory с this. Надеюсь, поможет:

class TableView extends React.Component {  
    state = {
        open: false,
    };

    onOpenModal = () => {
        this.setState({ open: true });
    };

    onCloseModal = () => {
        this.setState({ open: false });
    };

    render() {
        function showHistory() {
            this.onOpenModal(); // not able to do this
            console.info(this.state.open); // or this
        }.bind(this);
        return (
             //...
             //...
       );
   }
}

Вам нужно привязать метод в конструкторе или вы можете привязать его при его вызове,

 class TableView extends React.Component { 
       constructor(props){
       this.state = {
            open: false,
        };
       this.onOpenModal = this.onOpenModal.bind(this)
       this.onCloseModal = this.onCloseModal.bind(this)
         } 
        onOpenModal = () => {
            this.setState({ open: true });
        };

        onCloseModal = () => {
            this.setState({ open: false });
        };

        render() {
            function showHistory() {
                this.onOpenModal; // not able to do this
                console.info(this.state.open); // or this
            }
            return (
                 //...
                 //...
                <Modal open = {this.state.open} onClose = {this.onCloseModal} center>
                    <h2>History</h2>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                        pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet
                        hendrerit risus, sed porttitor quam.
                    </p>
                </Modal>
           );
       }
    }

Также обратите внимание,
В вашем случае состояние объявлено как свойства класса, а не как свойство экземпляра.

 state = {} //class property will not available on this object

Либо сделайте объявление состояния в конструкторе

constructor() {
  this.state = {};   // now state available on this object
}

или удалите это при обращении к состоянию. Лучше объявить состояние в конструкторе, поскольку вы используете метод this.setState

Я не уверен, почему вы хотите определять функцию внутри рендера, если ее можно определить на уровне класс / компонент.

Внутри класс / компонент вы можете разместить его параллельно для рендеринга.

showHistory = ()=> {
    this.onOpenModal(); // not able to do this
    console.info(this.state.open); // or this
}

Или же если вы хотите пойти с тем же размещением кода, определенным внутри рендеринга с помощью функции стрелки

const showHistory = () =>{
            this.onOpenModal; // not able to do this
            console.info(this.state.open); // or this
        }

И из html вызываем его вот так showHistory()

Другие вопросы по теме