W
W
Wasya UK2018-03-08 23:13:24
React
Wasya UK, 2018-03-08 23:13:24

Why is a request in react eternal?

I created a form, but it turned out that the data it receives from the server is needed in the App, in which it is rendered, in order to display all the news after the request. I redid it, but now the request is constantly repeated. What is the problem?

class Form extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      form: {
        username: ''
      }
    }

    this.onFormSubmit = this.onFormSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  onFormSubmit(e) {
    e.preventDefault();

    this.props.getData();
  }

  handleChange(event) {
    const { form } = this.state;

    form.username = event.target.value;

    this.setState({ form });
  }

  render() {
    const { tweets } = this.state;

    return (
      <form onSubmit={this.onFormSubmit}>
        <p className="leadform-component-container">
          <input type="text" placeholder="Username" required onChange={this.handleChange} />
        </p>
        <p className="leadform-component-container">
          <input type="submit" value="Press me" />
        </p>
      </form>
    )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tweets: []
    };
  }

  getData() {
    axios.post('/', {
      username: this.state.username
    })
    .then(({data: tweets}) => {
      console.log(tweets)
      this.setState({ tweets });
    })
    .catch(console.error);
  }

  render () {
    const { tweets } = this.state;
    console.log(tweets.length);

    if (tweets.length > 0 && tweets[0].user) {
      console.log(tweets.length);
      return (
        <div>
          <header>
            <Form getData={this.getData()} />
          </header>
          <main>
            <User user={tweets[0].user} />
            {tweets.map((tweet, i) => <Tweet key={i} tweet={tweet} />)}
          </main>
        </div>
      );
    } else {
      return (
        <Form getData={this.getData()} />
      );
    }
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2018-03-08
@dmc1989

You are not passing the getData method in the render method , but calling it and passing the result, which the method does not even return. You can fix it like this:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tweets: []
    };
  }

  getData = () => { 
    axios.post('/', {
      username: this.state.username
    })
    .then(({data: tweets}) => {
      console.log(tweets)
      this.setState({ tweets });
    })
    .catch(console.error);
  };

  render () {
    const { tweets } = this.state;
    console.log(tweets.length);

    if (tweets.length > 0 && tweets[0].user) {
      console.log(tweets.length);
      return (
        <div>
          <header>
            <Form getData={this.getData} />
          </header>
          <main>
            <User user={tweets[0].user} />
            {tweets.map((tweet, i) => <Tweet key={i} tweet={tweet} />)}
          </main>
        </div>
      );
    } else {
      return (
        <Form getData={this.getData} /> 
      );
    }
  }
}

Note that I have passed getData from a class method to a class property. Now when getData is an arrow function, it won't lose context when passed to another component. An alternative solution to the problem of losing context when passing a method is to bind this method in the constructor:
constructor(props) {
    super(props);
    this.state = {
      tweets: []
    };

    this.getData = this.getData.bind(this);
  }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question