Вызов функции каждый раз при визуализации компонента, так как componentDidMount () срабатывает только один раз - PullRequest
0 голосов
/ 27 сентября 2018

РЕДАКТИРОВАТЬ: После дальнейшего тестирования я понял, что componentDidMount ведет себя так, как я ожидал, но, похоже, это проблема с моей функцией рандомизации, которая по какой-то причине возвращает неопределенное значение, если она запускается во второй раз, поэтому при начальнойmount это дает мне результаты, когда я монтирую его снова, он возвращает undefined и, следовательно, ничего не рендерится ...

Я провел исследование, чтобы понять, почему у меня возникла эта проблема.У меня есть компонент для веб-приложения, который представляет собой просто баннер, который будет отображать имена спонсоров.Каждый раз, когда этот баннер отображается, я хочу рандомизировать порядок появления спонсоров.Я могу заставить это работать, но это происходит только при первом рендеринге (для componentDidMount ()), а затем каждый раз, когда я посещаю любой раздел, в котором визуализируется этот компонент, он больше не вызывает componentDidMount (), поэтому он не рендерит никакого контента.

Сначала я подумал, что componentDidMount () должен вызываться каждый раз, когда я вхожу в раздел, вызывающий этот компонент.После прочтения, везде говорили, что компонент монтируется один раз, и поэтому он вызывает функцию только один раз.Как сделать так, чтобы он каждый раз отображал компонент в случайном порядке?

Вот пример кода, который я пишу.

class SponsorBanner extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            randomized: []
        }

        this.randomizeSponsors = this.randomizeSponsors.bind(this)
    }

    randomizeSponsors(){
        let copy = []
        const array = ['a','b','c','d']
        let n = array.length
        let i;

        while(n){
            i = Math.floor(Math.random() * n--)
            copy.push(array.splice(i,1)[0])
        }

        let randomizedArray = copy.map((sponsor,i) => <div key={i}>{sponsor}</div>)

        this.setState({randomized:randomizedArray})

    }
    componentDidMount(){
        this.randomizeSponsors()
    }


    render(){

        return (
            <div>
                {this.state.randomized}
            </div>
        )
    }
}

Этот компонент визуализируется в 2 различных разделахприложение.Это очень простое приложение, и я даже не добавляю к нему маршрутизацию.Он просто работает как SPA.Когда пользователь щелкает раздел, он отображает этот компонент.При первой загрузке, если я посещаю раздел, который отображает этот компонент, он отображает рандомизированный массив.Если я перейду к другому разделу и вернусь, он отобразит пустой баннер.

Почему это происходит и как я могу обойти это ???

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Другим подходом может быть использование setIterval, если вы хотите, чтобы оно меняло каждую x сумму milliseconds.

Рабочий пример: https://codesandbox.io/s/k9zz9wq9lo

import random from "lodash/random";
import React, { Component } from "react";

export default class Banner extends Component {
  state = {
    randomIndex: 0
  };

  componentDidMount = () => this.setTimer();

  componentWillUnmount = () => this.clearTimer();

  clearTimer = () => clearInterval(this.timeout);

  timer = () => this.setState({ randomIndex: random(0, 999) });

  setTimer = () => (this.timeout = setInterval(this.timer, 3000));

  render = () => (
    <img
      src={`https://loremflickr.com/600/100?lock=${this.state.randomIndex}`}
    />
  );
}

Или, если вы не хотите использовать setIterval, и этот компонент всегда монтируется ... и вы хотите, чтобы он изменялся только при изменении состояния ..., тогда имейте HOC состояние управления компонентом.Затем вы можете использовать HOC render метод для обновления переменной.

Рабочий пример: https://codesandbox.io/s/6qvl49vqw

import random from "lodash/random";
import React, { Component } from "react";
import Sample from "./Sample";

export default class Parent extends Component {
  state = {
    loadC1: false
  };

  shouldComponentUpdate = (nextProps, nextState) =>
    this.state.loadC1 !== nextState.loadC1;

  handleClick = () =>
    this.setState(prevState => ({ loadC1: !this.state.loadC1 }));

  render = () => {
    const randomIndex = random(0, 999);
    const { loadC1 } = this.state;

    return (
      <div style={{ textAlign: "center" }}>
        <button
          className="uk-button uk-button-primary"
          onClick={this.handleClick}
        >
          {!loadC1 ? "Show" : "Hide"} Component
        </button>
        <div style={{ marginBottom: 40 }}>
          {loadC1 && <Sample />}
        </div>
        <img src={`https://loremflickr.com/600/100?lock=${randomIndex}`} />
      </div>
    );
  };
}
0 голосов
/ 27 сентября 2018

Если вы хотите, чтобы числа набирались случайным образом при каждом вызове render, добавьте эту логику в функцию render:

render() {
  const randomized = this.randomizeSponsors(); // IMPORTANT: CHANGE THIS TO MAKE IT RETURN ARRAY INSTEAD OF SETSTATE
  return (
    <div>
      {randomized}
    </div>
  );
}
...