@AlexMine
Учусь

Как правильно вызвать функцию в React?

Добрый день, помогите разобраться с вопросом. Решил написать приложение для вк, там используется реакт, не могу понять как правильно вызвать функцию в дочернем компоненте

Вот главный компонент App.js
import React from 'react';
import connect from '@vkontakte/vkui-connect';
import { View } from '@vkontakte/vkui';
import '@vkontakte/vkui/dist/vkui.css';
import Main from './panels/Main';
import NewAdvert from './panels/NewAdvert';

class App extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			activePanel: 'newadvert',
			fetchedUser: null,
			err: null,
		};
	}

	componentDidMount() {
		connect.subscribe((e) => {
			switch (e.detail.type) {
				case 'VKWebAppGetUserInfoResult':
					this.setState({ fetchedUser: e.detail.data });
					console.log('getUser')
					break;
				case 'VKWebAppAccessTokenReceived':
					this.setState({
						token: e.detail.data.access_token
					});
					this.getCountries()
					break;
				case 'VKWebAppAccessTokenFailed':
					console.log('token filed')
					break;
				case 'VKWebAppCallAPIMethodResult':
					if (e.detail.data.request_id === 'getcities') {
						this.setState({ cities: e.detail.data.response.items});
					} 
					break;
				case 'VKWebAppCallAPIMethodFailed':
					console.log(e.detail.data)
				default:
					console.log(e.detail.type);
			}
		});
		connect.send('VKWebAppGetUserInfo', {});
		this.getToken();
	}

	getToken = () => {
		connect.send("VKWebAppGetAuthToken", {"app_id": 6777159, "scope": "friends"});
	}
	getCities = (countryId, q) => {
		connect.send('VKWebAppCallAPIMethod', {
			'method': 'database.getCities',
			'request_id': 'getcities',
			'params': {
				'country_id': countryId,
				'q': q,
				'count': 100,
				'access_token': this.state.token,
				'v': '5.92',
			}
		});
	}
	go = (e) => {
		this.setState({ activePanel: e.currentTarget.dataset.to })
	};

	render() {
		return (
			<View activePanel={this.state.activePanel}>
				<Main id="main" data={this.state.data} user={this.state.fetchedUser} go={this.go}/>
				<NewAdvert id="newadvert" 
					user={this.state.fetchedUser}  
					cities={this.cities}
					getCities={this.getCities}
					getCity={this.getCity}
					token={this.state.token}
					getToken={this.getToken}
					go={this.go}
				/>
			</View>
		);
	}
}

export default App;


Вот дочерний компонент NewAdvert.js
class NewAdvert extends React.Component {
    constructor(props) {
        super(props)
        this.onChange = this.onChange.bind(this)
    }
    state = {
        activeView: 'newadvert',
        textSearch: '',

        country: '',
        countryId: '',
        userVkId: 0,
        city: '',
        section: '',
        category: '',
        age: '',
        
    }
    onChange (textSearch) {
        this.setState({textSearch});
    
    componentDidMount() {
        this.props.getCity(1, 'П');
    }
    render() {
        const props = this.props;
        return (
            <Root activeView={this.state.activeView}>
                <View activePanel="newadvert" id="newadvert">
                    <Panel id="newadvert" theme="white">
                        <PanelHeader>
                            Добавить объявление
                        </PanelHeader>
                        <FormLayout>
                            <SelectMimicry
                                top="Выберите Город"
                                placeholder="Не выбрана"
                                onClick={() => this.setState({ activeView: 'cities' })}
                            >{this.state.country}</SelectMimicry>
                        </FormLayout>
                    </Panel>
                </View>
                <View activePanel="cities" id="cities">
                    <Panel id="cities">
                        <PanelHeader>
                            Выбор города
                        </PanelHeader>
                        <Search value={this.state.textSearch} onChange={this.onChange}/>
                        {props.cities && props.cities.map((city) => 
                        <ListItem
                            key={city.id}
                            description={city.title}
                        >
                        </ListItem>)}                    
                    </Panel>
                </View>
            </Root>
        );
    }
}

export default NewAdvert;


Когда я вызываю в дочернем компоненте this.props.getCity(1, 'П')
Я получаю ошибку запроса, там передается пустой токен, но в родительском компоненте я же прям в функции указал откуда брать токен.
  • Вопрос задан
  • 1252 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
получаю ошибку

Текст ошибки показывать не надо, так держать (не так).

вызываю в дочернем компоненте this.props.getCity(1, 'П')

Которого, если верить показанному вами коду, нет. Смотрим, откуда берётся getCity в дочернем компоненте - видим, что getCity={this.getCity}, при этом метод getCity в родительском компоненте отсутствует. Есть getCities. Это как?

передается пустой токен

Если для корректного функционирования дочернего компонента нужен токен, то не надо рендерить компонент в его отсутствие, дождитесь получения:

{this.state.token && <NewAdvert id="newadvert" 
  user={this.state.fetchedUser}  
  cities={this.cities}
  getCities={this.getCities}
  getCity={this.getCity}
  token={this.state.token}
  getToken={this.getToken}
  go={this.go}
/>}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@afanasiyz
Javascript-разработчик
А я у вас в паренте не вижу метода getCity.
Его надо добавить как стрелочную функцию, если добавляется как то по другому.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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