A
A
Alexander2018-12-11 14:12:14
JavaScript
Alexander, 2018-12-11 14:12:14

How to correctly call a function in React?

Hello, please help me with this issue. I decided to write an application for VK, it uses React, I can’t figure out how to correctly call the function in the child component.
Here is the main App.js component

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;

Here is the child component of 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;

When I call this.props.getCity(1, 'P') in the child component,
I get a request error, an empty token is passed there, but in the parent component, I directly in the function indicated where to get the token from.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
0
0xD34F, 2018-12-11
@AlexMine

I get an error

The text of the error should not be shown, keep it up (not like that).
Which, according to the code you showed, is not. We look where getCity comes from in the child component - we see that getCity={this.getCity}, while the getCity method is absent in the parent component. There is getCities. What is it like?
If a token is needed for the correct functioning of the child component, then you do not need to render the component in its absence, wait for the receipt:
{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}
/>}

A
Afanasy Zakharov, 2018-12-11
@afanasiyz

And I don’t see the getCity method in your parent.
It must be added as an arrow function if it is added in some other way.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question