Guedda
@Guedda
Начинающий front-end разработчик

Почему родительский метод вызывается сам по себе?

Добрый день, уважаемые. Никак не пойму, что происходит.
Есть родительский компонент:
var inputData = {
    images: [
        'images/first-variant.png',
        'images/second-variant.png'
    ]
}

//.....

export default class Parent extends Component {

    constructor(props) {
        super(props);

        this.state = {
            page: 0,
            inputData: undefined,
            outputData: {
                variant: 0
            }
        }
    }

    getInputData() {
        // Показать, что тут будет вызов AJAX
        setTimeout(() => {
            this.setState({inputData: inputData, page: 1});
        }, 1000);
    }

    goNext(outputData) {
        let page = this.state.page;
        let obj = Object.assign({}, this.state.outputData, outputData);
        this.setState({page: ++page, outputData: obj});
    }

    componentDidMount() {
        this.getInputData();
    }

    render() {
        console.log(this.state.outputData);
        switch (this.state.page) {
            case 0:
                return (<p></p>);
            case 1:
                return (<FirstPage
                    data={this.state.inputData.images}
                    goNext={this.goNext.bind(this)} />
                );
            case 2:
                return (<div>Second page</div>);
        }
    }

}

И есть дочерний компонент:
export default class FirstPage extends Component {

    constructor(props) {
        super(props);
    }

    goNext(obj) {
        this.props.goNext(obj);
    }
    
    render() {
        let variants = this.props.data.map((item, index) => {
            let returnedObject = {
                variant: index
            }
            return (<img className="sample-img" onClick={this.goNext(returnedObject)} key={index} src={item} />);
        });
        return (<div>
            <h1>Choose variant</h1>
            {variants}
        </div>);
    }
}

Так вот когда я запускаю приложение, то сразу консоль мне выдает
Object
variant: 0
__proto__: Object

а через секунду ошибку:
Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

и обьект:
Object
variant: 1
__proto__: Object

Почему метод вызвался сам по себе? Простите, может нубский вопрос, но я не могу разобраться в нём.
Заранее спасибо за ответы.
  • Вопрос задан
  • 194 просмотра
Решения вопроса 1
maxfarseer
@maxfarseer
https://maxpfrontend.ru, обучаю реакту и компании
В onClick нужно передавать функцию-обработчик, а вы передаете функция-обработчик() === результат вашей функции...
То есть как только кнопка оказывается на странице, сразу же происходит вызов (круглые скобки).

Пример:
function myFunc(data) { console.log(data) }
console.log( myFunc('test') ) => выведеть в консоль 'test'
console.log( myFunc ) => выведеть в консоль function myFunc ...


P.S. естественно, сразу возникает вопрос - как передать функцию + аргумент... Вам нужен либо метод bind, либо анонимная функция... Есть у разных подходов плюсы-минусы, но я тем не менее люблю использовать data-аттрибуты для этого.. тогда при передаче функции обработчик, у меня в event.target.dataset - есть все что нужно.

P.P.S. когда возникают такие вопросы, значит нужно идти и копать основы, так как в дальнейшем только сильнее будет усиливаться непонимание между функциями, аргументами, полями свойств в props'ax и так далее... Начать по теории, рекомендую отсюда: https://learn.javascript.ru/function-basics, затем: https://learn.javascript.ru/introduction-browser-events
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы