Реагируйте на JavaScript, чтобы предотвратить отключение компонента - PullRequest
0 голосов
/ 18 декабря 2018

Я новичок в React JavaScript.Ранее я являлся разработчиком настольных приложений для WPF и широко использую Frame и Page для своих настольных приложений.Я хочу добиться почти того же с помощью React JavaScript.Я хочу сделать нижнюю панель вкладок с React JavaScript.Вот моя текущая работа:

App.js:

import './App.css';
import React, { Component } from 'react';
import BottomTabBar from './BottomTabBar/BottomTabBar';
import HomePage from './HomePage/HomePage';

class App extends Component {
  render() {
    let menuItems = [];

    menuItems.push({
      label: 'Home',
      faIcon: 'fas fa-home',
      content: (
        <HomePage/>
      )
    });

    menuItems.push({
      label: 'Numbers',
      faIcon: 'fas fa-ellipsis-h',
      content: (
        <h1>
          This is numbers page.
        </h1>
      )
    });

    menuItems.push({
      label: 'Notifications',
      faIcon: 'fas fa-bell',
      content: (
        <h1>
          This is notifications page.
        </h1>
      )
    });

    menuItems.push({
      label: 'Menu',
      faIcon: 'fas fa-bars',
      content: (
        <h1>
          This is menu page.
        </h1>
      )
    });

    return (
      <div 
        className='App'
      >
        <BottomTabBar
          menuItems={menuItems}
        />
      </div>
    );
  }
}

export default App;

BottomTabBar.js:

import './BottomTabBar.css';
import '../Ripple.css';
import React, { Component } from 'react';

class BottomTabBar extends Component {
  constructor() {
    super();

    this.state = {
      content: null,
      selectedTabIndex: 0,
    };
  }

  handleClick = (index) => {
    // Changing content.
    this.setState({
      selectedTabIndex: index
    });
  }

  render() {
    // Putting them all.
    return (
      <div
        className='BottomTabBar'
      >
        <div
          className='Content'
        >
          {this.props.menuItems[this.state.selectedTabIndex].content}
        </div>

        <div
          className='IconsBar'
        >
          {
            this.props.menuItems.map((menuItem, i) => {
              return (
                <div
                  className="MenuItem Ripple"
                  key={i}
                  onClick={()=>this.handleClick(i)}
                >
                  <div
                    className="Gap"
                  />
                  <div
                    className="Icon"
                  >
                    <div
                      className={menuItem.faIcon}
                    />
                  </div>
                  <div
                    className="Gap"
                  />
                  <div
                    className="Text"
                  >
                    {menuItem.label}
                  </div>
                </div>
              )
            })
          }
        </div>
      </div>
    );
  }
}

export default BottomTabBar;

HomePage.js:

import './HomePage.css';
import React, { Component } from 'react';

class HomePage extends Component {
  constructor() {
    super();

    this.state = {
      counter: 0,
    };
  }

  componentDidMount() {
    this.counterInterval = setInterval(() => {
      this.setState((prevState) => ({
        counter: prevState.counter + 1
      }));
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.counterInterval);
  }

  render() {
    return (
      <div
        className='HomePage'
      >
        Home page counter: {this.state.counter}
      </div>
    );
  }
}

export default HomePage;

Как вы, возможно, знаете из приведенных выше кодов, моя домашняя страница представляет собой простую страницу с автоматическим приращением счетчика в секунду:

Обычная домашняя страница:
Normal home page

Проблема в том, что мой HomePage не может быть постоянным.Если я пытался переключаться между вкладками, это работает, но счетчик на домашней странице всегда сбрасывается в 0, что означает, что моя домашняя страница и другие страницы воссоздаются только потому, что они перемещаются между вкладками.Это очень странно для меня, когда я создал <HomePage/> в строке App.js 14. Что я делаю не так?Не стесняйтесь спрашивать меня, если вам нужна дополнительная информация.

Может быть, я пытаюсь сделать что-то похожее на эту библиотеку:

https://github.com/lishengzxc/react-no-unmount-hide

Я недействительно уверен, что эта библиотека делает, но я попробовал, и она не работает (просто выдает странную ошибку)

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Ожидается, потому что каждый раз при открытии вкладки Home создается новый экземпляр HomePage.

В этом случае поднимает состояние вверх .Если состояние счетчика должно сохраняться, его следует переместить в компонент, который не разрушается при навигации по вкладкам, например App:

class App extends Component {
  state = { counter: 0 };

  incrementCounter = () => setState((state) => ({ counter: state.counter + 1 }));

  render() {
    let menuItems = [];

    menuItems.push({
      label: 'Home',
      faIcon: 'fas fa-home',
      content: (
        <HomePage counter={this.state.counter} increment={this.incrementCounter} />
      )
    });
    ...

Эти реквизиты следует использовать вместо локального HomePage состояния:

this.counterInterval = setInterval(this.props.increment);

и

Home page counter: {this.props.counter}

Альтернативой является использование API контекста Redux или React для управления глобальным состоянием приложения.

0 голосов
/ 18 декабря 2018

После нескольких часов борьбы мне наконец удалось сделать это, основываясь на моей идее.Вот код для тех, кому интересно:

App.js:

import './App.css';
import React, { Component } from 'react';
import BottomTabBar from './BottomTabBar/BottomTabBar';
import HomePage from './HomePage/HomePage';
import NumbersPage from './NumbersPage/NumbersPage';

class App extends Component {
  render() {
    let menuItems = [];

    menuItems.push({
      label: 'Home',
      faIcon: 'fas fa-home'
    });

    menuItems.push({
      label: 'Numbers',
      faIcon: 'fas fa-ellipsis-h'
    });

    return (
      <div 
        className='App'
      >
        <BottomTabBar
          menuItems={menuItems}
        >
          <HomePage/>
          <NumbersPage/>
        </BottomTabBar>
      </div>
    );
  }
}

export default App;

BottomTabBar.js:

import './BottomTabBar.css';
import '../Ripple.css';
import React, { Component } from 'react';

class BottomTabBar extends Component {
  constructor() {
    super();

    this.state = {
      selectedIndex: 0,
    };

    console.log('Initialized bottom tab bar');
  }

  handleClick = (index) => {
    // Changing content.
    this.setState({
      selectedIndex: index
    });
  }

  render() {
    return (
      <div
        className='BottomTabBar'
      >
        <div
          className='Content'
        >
          {
            this.props.children.map((child, i) => {
              return (
                <div
                  style={{
                    display: i == this.state.selectedIndex
                    ? 'block'
                    : 'none'
                  }}
                  key={i}
                >
                  {child}
                </div>
              )
            })
          }
        </div>

        <div
          className='IconsBar'
        >
          {
            this.props.menuItems.map((menuItem, i) => {
              return (
                <div
                  className="MenuItem Ripple"
                  key={i}
                  onClick={()=>this.handleClick(i)}
                >
                  <div
                    className="Gap"
                  />
                  <div
                    className="Icon"
                  >
                    <div
                      className={menuItem.faIcon}
                    />
                  </div>
                  <div
                    className="Gap"
                  />
                  <div
                    className="Text"
                  >
                    {menuItem.label}
                  </div>
                </div>
              )
            })
          }
        </div>
      </div>
    );
  }
}

export default BottomTabBar;

HomePage.js:

import './HomePage.css';
import React, { Component } from 'react';

class HomePage extends Component {
  constructor() {
    super();

    this.state = {
      counter: 0,
    };

    console.log('Initialized home page');
  }

  componentDidMount() {
    this.counterInterval = setInterval(() => {
      this.setState((prevState) => ({
        counter: prevState.counter + 1
      }));
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.counterInterval);
  }

  render() {
    return (
      <div
        className='HomePage'
        style={this.props.style}
      >
        Home page counter: {this.state.counter}
      </div>
    );
  }
}

export default HomePage;

Примечание: NumbersPage.js - это просто страница с очень длинным текстом lorem ipsum.

То есть все состояния сохраняются без поднятия.Положение прокрутки на NumbersPage.js не сохраняется, потому что я играл со свойством css display там, и это нормально:)

Спасибо за помощь!

0 голосов
/ 18 декабря 2018

Вы должны использовать компонентыact-router-dom для целей линковки и навигации.

Этот проект основан на том, чего вы хотите достичь.Проверьте это

https://github.com/onejeet/image-sharing-app

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...