【问题标题】:component state's var disappears after changing it outside组件状态的 var 在外部更改后消失
【发布时间】:2019-11-23 00:47:04
【问题描述】:
  1. redux 存储语言的区域设置
  2. translator 组件通过 key 从 const 获取翻译并将其保存到自己的状态。并在 span 中返回当前语言的翻译
  3. 我正在尝试使用这个库https://www.npmjs.com/package/baffle 来获得精美的效果。
  4. 只要翻译组件中的纯文本,一切正常。但是当文本取决于状态时,文本就会消失。 不确定我是否解释正确,所以有一个小例子。 任何文字 - 作品 {this.state.etc} - 没有

翻译.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',
    },
  },
}

有没有办法解决这个问题? 翻译工作正常,切换语言工作。 链接有效。 如果翻译器返回没有状态的 span,即使是 baffle 也能正常工作。 但是如果翻译器返回依赖于状态的文本,文本就会消失,当挡板启动任何功能时

【问题讨论】:

  • 你能否在你的componentDidMount中打印TRANSLATIONS的值和translationKeys变量并在sn-p中显示出来
  • @anuragb26 translationKey 看起来像“navBar.home”
  • 我没有看到在 Translate 组件中调用 setState 的真正理由。
  • @Hosar 不是在性能上更好,而不是在每次渲染时循环遍历 json 吗?我还不知道 react 在低级别是如何工作的

标签: javascript reactjs redux


【解决方案1】:
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 对象,甚至在渲染中而不是 componentDidMount。您不需要状态,因为您似乎没有再次设置状态的事件处理程序。

【讨论】:

  • 感谢您的回答。但我认为我确实需要循环。翻译会更深,所以可能会有超过 2 个步骤的键。和关于状态。我不确定,但这不是性能友好的解决方案吗?否则我将需要在任何时候循环通过 json 更改语言。还是我错了?
猜你喜欢
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
  • 2018-07-18
  • 2014-11-19
  • 2021-10-06
  • 1970-01-01
相关资源
最近更新 更多