组件状态的var在外部更改后消失

时间:2019-07-13 15:58:02

标签: javascript reactjs redux

  1. redux存储语言的语言环境
  2. 翻译器组件通过键从const获取翻译,并将其保存到自己的状态。并以跨度返回当前语言的翻译
  3. 我正尝试使用此库https://www.npmjs.com/package/baffle来达到理想效果。
  4. 一切都很好,仅在翻译组件中使用纯文本即可。但是当文本取决于状态时,文本就会消失。 不知道我是否解释正确,所以有一个小例子。 任何文字-作品 {this.state.etc}-不

Translate.jsx

import { TRANSLATIONS } from './../../constants/translations';

class Translate extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      translations: {},
    }
  }

  componentDidMount() {
    const translationKeys = this.props.translationKey.split('.');
    let translation = TRANSLATIONS;

    translationKeys.forEach((i) => {
      translation = translation[i]
    });

    this.setState((state) => ({
      translations: translation,
    }));
  }

  render() {
    return (
      <span ref={this.props.translateRef}>{this.state.translations[this.props.locale]}</span>
    )
  }
}


Translate.propTypes = {
  locale        : PropTypes.string.isRequired,
  translationKey: PropTypes.string.isRequired,
}

export default Translate;

TranslateContainer.js

const mapStateToProps = state => ({
  locale: state.locale,
})

export default connect(mapStateToProps, null, null, {forwardRef: true})(Translate);

并且我在react-router-dom自定义链接中使用此组件

import { Route, Link } from 'react-router-dom';
import classNames from 'classnames';
import baffle from 'baffle';

import css from './RouteLink.module.css';

import Translate from '../Translations/TranslateContainer';

class RouteLink extends React.Component {
  constructor(props) {
    super(props);

    this.baffleRef = React.createRef();

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

  componentDidMount() {
    this.baffle = baffle(this.baffleRef.current);
  };

  _onMouseEnter() {
    this.baffle.start();
  }

  render() {
    return (
      <Route
      path={this.props.to}
      exact={this.props.active}
      children={({ match }) => (
        <Link
        to={this.props.to}
        className={classNames({
          [css.link]: true,
          [css.active]: match,
        })}
      onMouseEnter={this._onMouseEnter}
        >
          <Translate
          translationKey={this.props.label}
          translateRef={this.baffleRef}/>
        </Link>
      )}
      />
    );
  }
}

RouteLink.propTypes = {
  to    : PropTypes.string.isRequired,
  label : PropTypes.string.isRequired,
  active: PropTypes.bool,
}

export default RouteLink;

translations.js

export const TRANSLATIONS = {
  navBar: {
    home: {
      ru_RU: 'Главная',
      en_EN: 'Home',
    },
  },
}

有什么办法可以解决这个问题? 翻译效果很好,切换语言效果很好。 链接有效。 如果翻译器返回跨度而没有状态,那么即使是折流板也可以工作。 但是,如果翻译程序返回的文本取决于状态,那么当挡板启动任何功能时,文本只会消失

1 个答案:

答案 0 :(得分:0)

I don't see the need for the forEach loop in componentDidMount.

The line below will return an array of 2 elements ['navbar','home']

const [firstLevel,secondLevel] = this.props.translationKey.split('.') // array destructuring to get the two values

You could just use the values in the array and locale props to set your translation state.

this.setState({translations: TRANSLATIONS[firstLevel][secondLevel][this.props.locale]})

然后在渲染中,仅使用状态

<span ref={this.props.translateRef}>{this.state.translations}</span>

这可以解决问题,但作为一个旁注,您可以拆分props.translationKey并遍历TRANSLATIONS对象,甚至可以在render内,而不是componentDidMount。您不需要状态,因为您似乎不需要再次设置setState的事件处理程序。