重新渲染React和Redux中的所有组件

时间:2017-02-01 15:57:45

标签: javascript reactjs localization react-redux

我有简单的应用程序:

import React, { Component } from 'react';
import MainPage from './MainPage';
import { setLanguage, currentLanguage, availableLanguages } from '../localization';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as appActions from '../actions/appActions';
class App extends Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    $('.dropdown-button').dropdown();
  }
  setLanguageHandle(twoLetter, e) {
    e.preventDefault();
    setLanguage(twoLetter);
  }
  render() {
    return (
      <div>
        <ul id='languageDropdown' className='dropdown-content'>
          {availableLanguages().map((item, i) =>
            <li key={i}><a href='' onClick={this.setLanguageHandle.bind(this, item.twoLetterISOLanguageName)}>{item.nativeName}</a></li>
            )}
        </ul>
        <nav className='cyan'>
          <div className='nav-wrapper'>
            <a className='brand-logo' style={{ marginLeft: 16 }}>SUPP</a>
            <ul className='right hide-on-med-and-down'>
              <li>
                <a className='dropdown-button' href='' data-activates='languageDropdown'>
                  {currentLanguage().nativeName}
                  <i className='material-icons right'>arrow_drop_down</i>
                </a>
              </li>
            </ul>
          </div>
        </nav>
        <div className='container'>
          <MainPage />
        </div>
        <footer className='page-footer cyan'>
          <div className='footer-copyright'>
            <div className='container'>
              <span style={{ fontWeight: 'normal' }}>© 2017</span>
            </div>
          </div>
        </footer>
      </div>
    )
  }
}

function mapStateToProps() {
  return {
  }
}

function mapDispatchToProps(dispatch) {
  return {
    appActions: bindActionCreators(appActions, dispatch)
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

这里我有简单的本地化下拉列表,我点击语言,然后它会触发setLanguageHandle。来自setLanguage的{​​{1}}使用Cookie来设置语言。

../localization组件及其子项从Redux加载其所有属性。本地化是唯一的例外,看起来像MainPage,它使用:

_localize('sometext')

因此,本地化不使用Redux。

问题是,当我改变文化时,子组件不会重新渲染。我试图调用我的合成Redux动作,它在商店中更改了一个自变量,但没有重新渲染,似乎它太聪明了,不能做这样的工作。

当我呼叫export function _(key) { let currentCulture = getCurrentCultureFromCookie(); let translation = translations[currentCulture]['translations'][key]; return translation; } 提供动态文化切换时,如何重新渲染整个应用程序中的所有组件?也许还有另一种方法可以做到这一点,不用重新加载整个页面就可以了吗?

1 个答案:

答案 0 :(得分:2)

我认为最好的方法是使用redux进行本地化。具体来说,我认为你应该把&#34; currentCulture&#34;进入你的商店。然后将调用替换为&#34; _localize&#34;具有Localize组件的方法可能类似于以下内容:

import React from "react";
import { connect } from "react-redux";

function Localize(props) {
    return (
        <span>{translations[props.currentCulture]['translations'][props.textKey]}</span>
    );
}

const mapStateToProps = (state) => {
  return {currentCulture: state.currentCulture};
};
const LocalizeContainer = connect(mapStateToProps)(Localize);
export default LocalizeContainer;

然后您可以使用以下内容:

<Localize textKey="sometext" />

我意识到这是方法上的一个重大变化,但我认为您通过让部分渲染由不在您所在州的变量控制来要求头痛。

可以更灵活地使用的替代/补充方法(例如在属性值中)将是一个注入&#34;本地化&#34;方法作为包装组件的属性。

在&#34; localize.js&#34;:

import { connect } from "react-redux";

const localizeText = currentCulture => textKey => { return translations[currentCulture]['translations'][textKey]; };

const mapStateToProps = (state) => {
  return { localize: localizeText(state.currentCulture) };
};

export default function localize(LocalizedComponent) {
  return connect(mapStateToProps)(LocalizedComponent);
}

然后使用它:

import React from "react";
import localize from "./localize.js"

function YourDisplayComponent(props) {
    return (
        <input value={props.localize(props.inputValueKey)}>
    );
}
export default localize(YourDisplayComponent);