简体   繁体   中英

component state's var disappears after changing it outside

  1. redux stores language's locale
  2. translator component gets translations from const via key and saves it to their own state. and returns current language's translation in span
  3. im trying to use this library https://www.npmjs.com/package/baffle for fancy effect.
  4. everything works fine with just plain text in translation component. but text disappears, when text depends on state. not sure if i explained correctly, so there is a little example. any text - works {this.state.etc} - doesn't

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);

and im using this component in react-router-dom custom links

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',
    },
  },
}

Is there any way to fix this? Translations works just fine, switching language works. Links work. And if translator returns span without state, even baffle works. But if translator returns text that depends on state, text just disappears, when baffle starts any function

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]})

Then in your render,just use your state

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

This would solve the issue but as a sidenote,you can do the splitting of props.translationKey and traversing the TRANSLATIONS object even within the render instead of componentDidMount.You don't need the state as you don't seem to have an event handler to setState again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM