@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, 'П')
Я получаю ошибку запроса, там передается пустой токен, но в родительском компоненте я же прям в функции указал откуда брать токен.
  • Вопрос задан
  • 1265 просмотров
Решения вопроса 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.
Его надо добавить как стрелочную функцию, если добавляется как то по другому.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы