Реагировать на условный рендеринг в зависимости от размера области просмотра

Это должно быть легко для вас, монстров React. :) У меня есть условие, но я не могу понять, как обработать размер области просмотра в моем конструкторе, чтобы условие работало. Я просто хочу показать один элемент, когда размер области просмотра составляет 1451 пикселей или больше, а другой - 1450 пикселей или меньше.

Это мой код (упрощенный)

class My Class extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isDesktop: "1450px" //This is where I am having problems
        };
    }

    render() {
        const isDesktop = this.state.isDesktop;

        return (
            <div>
                {isDesktop ? (
                    <div>I show on 1451px or higher</div>
                ) : (
                    <div>I show on 1450px or lower</div>
                )}
            </div>
        );
    }
}

Возможно, мне предложат работать с ComponentWillMount или ComponentDidMount. Честно говоря, не уверен. Я новичок в React.

Заранее спасибо, ребята.


person LOTUSMS    schedule 05.10.2017    source источник
comment
Вы хотите обновить isDesktop при изменении размера страницы?   -  person Kristaps Taube    schedule 05.10.2017
comment
ммм, хороший вопрос. Я бы сказал да. Когда пользователь изменяет размер, когда ширина падает ниже 1450 пикселей, он должен отображать правильный компонент. Я пытаюсь тренировать отзывчивость без CSS   -  person LOTUSMS    schedule 05.10.2017


Ответы (5)


Возможно, мне предложат работать с ComponentWillMount или ComponentDidMount

Да, вам нужно отслеживать событие resize и обновлять внутреннее состояние при изменении. Вы можете сделать это, добавив обработчик событий при монтировании компонента. Попробуйте полный пример здесь.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isDesktop: false //This is where I am having problems
    };

    this.updatePredicate = this.updatePredicate.bind(this);
  }
  componentDidMount() {
    this.updatePredicate();
    window.addEventListener("resize", this.updatePredicate);
  }

  componentWillUnmount() {
    window.removeEventListener("resize", this.updatePredicate);
  }

  updatePredicate() {
    this.setState({ isDesktop: window.innerWidth > 1450 });
  }

  render() {
    const isDesktop = this.state.isDesktop;

    return (
      <div>
        {isDesktop ? (
          <div>I show on 1451px or higher</div>
        ) : (
          <div>I show on 1450px or lower</div>
        )}
      </div>
    );
  }
}
person Kristaps Taube    schedule 05.10.2017
comment
Это было золото! Теперь я понимаю концепцию. Я смогу использовать эту концепцию в других условиях, которые мне нужно отработать. Спасибо! - person LOTUSMS; 05.10.2017
comment
Хороший ответ, подробно показывает архитектуру условного изменения состояния. - person serraosays; 11.07.2019

Просто для того, чтобы опубликовать здесь недавнее обновление после того, как у меня возникла такая же проблема, но настроил его с помощью функционального компонента и useEffect / useState React Hooks:

const MyFunction = () => {
  const [isDesktop, setDesktop] = useState(window.innerWidth > 1450);

  const updateMedia = () => {
    setDesktop(window.innerWidth > 1450);
  };

  useEffect(() => {
    window.addEventListener("resize", updateMedia);
    return () => window.removeEventListener("resize", updateMedia);
  });

  return (
    <div>
      {isDesktop ? (
        <div>I show on 1451px or higher</div>
      ) : (
        <div>I show on 1450px or lower</div>
      )}
    </div>
  );
}
person foakesm    schedule 23.03.2020
comment
вроде буквально скопировал, вставил и отредактировал, и это сработало, yasssssss! БЛАГОДАРЮ ВАС! @foakesm - person Angela Inniss; 01.05.2020

проблема с вашим кодом заключается в том, что он работает только в том случае, если происходит изменение размера, здесь у меня есть функция handleWindowResiz, которая установит ширину на window.innerWidth и сравнивает ее с breakPoint для условного рендеринга вашего пользовательского интерфейса, если пользователь изменяет размер экрана, прослушиватель событий будет будет запущен, и будет вызван handleWindowResiz, и он сбросит width на новый window.innerWidth, и вы получите желаемый пользовательский интерфейс. Таким образом, пользовательский интерфейс всегда отображается правильно при первом отрисовке компонента и при изменении пользователем ширины экрана.

const MyFunction = () => {

  const [width, setWidth] = React.useState(window.innerWidth);
  const breakPoint = 1450;

 

  useEffect(() => {
   const handleWindowResize = () => setWidth(window.innerWidth);
   window.addEventListener("resize", handleWindowResize);

    
   return () => window.removeEventListener("resize", handleWindowResize);
  },[]);

  return (
    <div>
      {width > breakPoint? (
        <div>I show on 1451px or higher</div>
      ) : (
        <div>I show on 1450px or lower</div>
      )}
    </div>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

person ahlambey    schedule 17.12.2020
comment
Было бы неплохо, если бы вы объяснили, что делаете со своим кодом. - person GaryNLOL; 17.12.2020
comment
когда компонент визуализируется в первый раз, функция handleWindowResize устанавливает начальную ширину, а затем мы сравниваем ширину с точкой останова, чтобы выбрать, что должно быть отрисовано ‹div› Я показываю на 1451px или выше ‹/div› или ‹div› I показать на 1450px или ниже ‹/div›, и при изменении размера окна будет запущен приемник событий, и ширина будет сброшена до новой ширины окна. так что здесь отличается то, что даже когда компонент сначала визуализируется, мы можем получить ширину окна и выполнить условный рендеринг. Надеюсь, я смог хорошо объяснить себя :) - person ahlambey; 17.12.2020
comment
Пожалуйста, помещайте объяснение в ответ, а не в комментарий. - person Adrian Mole; 17.12.2020

class My Class extends React.Component {
  constructor(props) {
      super(props);
      this.state = {
          isDesktop: window.innerHeight > 1450,
      };
  }

  render() {
      const isDesktop = this.state.isDesktop;

      return (
          <div>
              {isDesktop ? (
                  <div>I show on 1451px or higher</div>
              ) : (
                  <div>I show on 1450px or lower</div>
              )}
          </div>
      );
  }}

Дополнительная информация: Получить высоту окна просмотра / окна в ReactJS

person bobu    schedule 05.10.2017
comment
К сожалению, это не сработало, также мое внимание привлек innerHeight. Разве вы не обрабатываете высоту вместо ширины? Я имею в виду обрабатывать ширину области просмотра. Я попробовал innerWidth, и это тоже не сработало. Я не проверял предоставленную вами ссылку - person LOTUSMS; 05.10.2017
comment
Вы можете создать слушателя изменения размера с функцией обратного вызова, в которой вы можете изменить состояние isDesktop, в настоящее время эта реализация работает только при обновлении страницы - person bobu; 05.10.2017

если вы используете NextJS ... вы получите сообщение об ошибке: окно не определено. Вот код без ошибок, наслаждайтесь.

Сначала я проверяю, если размер окна больше или меньше 1450 пикселей (потому что, если пользователь никогда не изменяет размер окна, весь код будет бесполезен)

Но мне также нужно проверить, изменяет ли пользователь размер окна ... посмотрите сами

    export default function MyFunction() {
        const [isDesktop, setDesktop] = useState(false);

  useEffect(() => {
    if (window.innerWidth > 1450) {
      setDesktop(true);
    } else {
      setDesktop(false);
    }

    const updateMedia = () => {
      if (window.innerWidth > 1450) {
        setDesktop(true);
      } else {
        setDesktop(false);
      }
    };
    window.addEventListener('resize', updateMedia);
    return () => window.removeEventListener('resize', updateMedia);
  }, []);
    
      return (
          <div>
              {isDesktop ? (
                  <div>I show on 1451px or higher</div>
              ) : (
                  <div>I show on 1450px or lower</div>
              )}
          </div>
      );
    }
person sylvain s    schedule 24.07.2021