【问题标题】:Reactjs, reducers, language switchingReactjs、reducers、语言切换
【发布时间】:2017-05-11 23:21:26
【问题描述】:

我刚刚接手了一个新的 reactjs 项目——我正在尝试查看语言切换是如何被调用的。

所以就像页脚中有两个链接可以进行这种语言切换。

//footer.js

import React from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { selectLanguage, getLangDetails } from '../../actions/action_language'
import langObject from './Footer.lang'

class Footer extends React.Component {
  constructor (props) {
    super(props)
    this.changeLanguageToGerman = this.changeLanguageToGerman.bind(this)
    this.changeLanguageToEnglish = this.changeLanguageToEnglish.bind(this)
  } 

  changeLanguageToGerman () {
    this.props.selectLanguage('de')
  }

  changeLanguageToEnglish () {
    this.props.selectLanguage('en')
  } 

  render () {
    let activeLang = 'language--active'
    let alternativeLang = 'language--hover'
    const lang = getLangDetails(this.props.active_language, langObject)
    return (
      <div>
        <footer className='main-footer show-for-medium-only'>
          <div className='medium-15 columns'>
            <p className='text--white grid__row--offset--15 footer-text'>
              <Link to={this.props.deURL} className={`text--white footer-text ${this.props.active_language === 'de' ? activeLang : alternativeLang}`} onClick={this.changeLanguageToGerman}>DE</Link>
              &nbsp;&nbsp;&#124;&nbsp;&nbsp;
              <Link to={this.props.enURL} className={`text--white footer-text ${this.props.active_language === 'en' ? activeLang : alternativeLang}`} onClick={this.changeLanguageToEnglish}>EN</Link>
            </p>
          </div>
        </footer>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    active_language: state.active_language
  }
}

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

const { string, func } = React.PropTypes
Footer.propTypes = {
  deURL: string,
  enURL: string,
  selectLanguage: func,
  active_language: string
}

export default connect(mapStateToProps, mapDispatchToProps)(Footer)

// header.js

import React from 'react'
import { connect } from 'react-redux'
import { getLangDetails } from '../../actions/action_language'
import langObject from './Header.lang'

class Header extends React.Component {
  render () {
    let transparent
    transparent = this.props.transparent ? 'transparent' : ''
    const lang = getLangDetails(this.props.active_language, langObject)
    return (
      <div>
        <header className={` main_headerbar__landing transition show-for-large-up ${transparent} `}>
          <div className='contain-to-grid'>
            {lang}
          </div>
        </header>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    active_language: state.active_language
  }
}

const { bool, string } = React.PropTypes
Header.propTypes = {
  transparent: bool,
  active_language: string
}

export default connect(mapStateToProps)(Header)

--- 所以这些是页眉/页脚组件 - 每个都有一个 json 文件,该文件拆分成一个 lang 数组。

有一个看起来像一些全局 js 的文件,我认为它与此挂钩 - 但我正在努力将此功能扩展到站点组件/页面的其余部分

//action_language.js

export const LANGUAGE_SELECTED = 'LANGUAGE_SELECTED'

export function selectLanguage (language) {
  return {
    type: LANGUAGE_SELECTED,
    payload: language
  }
}

export function getLangDetails (language = 'de', langObject) {
  const langData = langObject.langs.filter((langVar) => langVar.lang === language)
  return langData['0'].lines
}

好的——这是第一页——称为服务。现在让我首先想到的是而不是使用 active_language 它现在只是语言。

//services.js

import React from 'react'
import Header from '../HeaderLanding/Header'
import Footer from '../Footer/Footer'
import NoBundle from './NoBundle'
import HowTiles from './HowTiles'
import CarouselTiles from './CarouselTiles'
import YourAdvantages from './YourAdvantages'
import InformationTiles from './InformationTiles'
import ContactTiles from './ContactTiles'

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { selectLanguage, getLangDetails } from '../../actions/action_language'

// language file
import langObject from './services.lang.json'

//  services css
import './services.css'

// getting the distinct URLs from the lang files
const deURL = langObject.langs[0].pageURL
const enURL = langObject.langs[1].pageURL

const Spacers = () => (
  <div>
    <div className='row show-for-large-up' style={{ height: '250px' }} />
    <div className='row show-for-medium-only' style={{ height: '150px' }} />
    <div className='row show-for-small-only' style={{ height: '80px' }} />
  </div>
)

class Services extends React.Component {
  constructor (props) {
    super(props)
    this.language = props.match.params.langURL
  }
  componentWillMount () {
    document.getElementById('body').className = 'overlay-background-services'

    this.updateLanguage()
  }
  updateLanguage () {
    console.log('updatelang', this.language)
    if (this.language === 'de' || !this.language) {
      this.props.selectLanguage('de')
    } else {
      this.props.selectLanguage('en')
    }
  }
  componentWillUnmount () {
    document.getElementById('body').className = ''
  }

  render () {
    const lang = getLangDetails(this.language, langObject)
    return (
      <div>
        <Header transparent />
        <Spacers />
        <NoBundle lang={lang} />
        <HowTiles />
        <CarouselTiles />
        <YourAdvantages />
        <InformationTiles />
        <ContactTiles />
        <Footer deURL={deURL} enURL={enURL} />
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    language: state.language
  }
}

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

const { func, string, object } = React.PropTypes
Services.propTypes = {
  selectLanguage: func,
  langURL: string,
  params: object,
  match: object
}

export default connect(mapStateToProps, mapDispatchToProps)(Services)

【问题讨论】:

  • 您能更具体地说明您遇到的问题吗?很难回答你的问题,因为好吧..你还没有真正提出问题
  • 好吧——我很难把它放在一个问题中。本质上,您有一个通过页脚中的两个链接调用的开关——因此它会导致页脚的语言内容发生变化——使用来自 json 文件的数据。 - 标题也正确地接受了这个变化。 -- 我想我的第一个问题是 -- 这是解决这个问题的最佳方法吗 - 只关注页眉/页脚代码 -- 第二个问题是在网站的其他部分携带这个逻辑
  • 您的第一个问题:我不知道有关您的应用程序的任何其他信息.. 但这似乎是明智的。你的第二个问题仍然不是问题。也许先尝试在某个地方做......也许它会起作用,错误或者你会被卡住尝试,。然后回来问
  • 我遇到的问题 - 我开始在处理实际页面的组件中添加类似的逻辑处理 - 它由较小的组件组​​成 - 在将页面刷新到该页面时效果很好url -- 但不会在交换机上更新
  • 我认为我的页面文件中的 mapStateToProps -- 似乎没有在更改时更新 -- 不像页眉/页脚

标签: javascript reactjs reducers


【解决方案1】:

Footer 组件通过调用 Redux 操作创建者 selectLanguage 来处理设置当前语言。本质上,这会将一个操作(您可以将其视为具有一些相应数据 - 语言的自定义事件)发送到商店,该商店将保留用户的语言选择以在其他地方使用。

为了在其他组件中使用该语言,需要将该语言选择从 Redux 存储传递到组件(在本例中为 Header)。

这是标题中感兴趣的代码......

const mapStateToProps = (state) => {
  return {
    active_language: state.active_language
  }
}

export default connect(mapStateToProps)(Header)

在这里,您将 Header 连接到 store,并使用一个函数描述 store 应如何将值映射到 react 组件上的 props。 state.active_language 是存储用户选择的语言的位置,这告诉它在您的 Header 组件上作为名为 active_language 的道具传递

connect 函数是一个装饰器,它将创建所谓的高阶组件 (HOC),它本质上是一个自动注入道具或功能的组件(在这种情况下,使用自动传递的 @ 值进行装饰) 987654326@来自商店的道具)

您可以对需要此语言设置的任何其他组件执行相同的操作,或者更进一步

而不是传递活动语言名称,而是传递相应的语言本身...

import { getLangDetails } from '../../actions/action_language'
import langObject from './Header.lang'

const mapStateToProps = (state) => {
  return {
    active_language: getLangDetails(state.active_language, langObject)
  }
}

export default connect(mapStateToProps)(Header)

或者更好的是编写另一个 HOC 来包装您通过此信息传递的任何组件...

import { getLangDetails } from '../../actions/action_language'

export default const injectLanguage = (component, langObject) => connect((state) => ({
    language: getLangDetails(state.active_language, langObject)
  })
)(component)

然后在后续组件中用language 属性,用这个装饰

import injectLanguage from './some/where'
import langObject from './MyLanguageDetailsAwareComponent.lang'

class MyLanguageDetailsAwareComponent extends React.Component {

  render() {
    return this.props.language
  }

}

export default injectLanguage(MyLanguageDetailsAwareComponent, langObject)

【讨论】:

  • 您好@alechill 我已经更新了问题 - 向您展示我在页面核心部分切换语言时遇到的问题 -- service.js
  • 看起来它是通过存储道具作为language 传递的并且从未使用过,并且还来自路由或匹配的东西,然后将存储值重置为路由中匹配的任何内容每个组件更新,完全忽略和覆盖存储。看起来您的页面和页脚选择器正在相互对抗,页面获胜
  • 如果用户已经设置了this.language = props.language || props.match.params.langURL,则更改为this.language = props.language || props.match.params.langURL 会更喜欢商店设置,但会将其默认为我认为是我认为是第一次使用的路线的语言。抱歉,我现在正在打电话,所以这些内容不太详细
  • ——这些都是好主意——我明天自己会尝试好好研究一下——我没有写这段代码,所以逆向工程对我来说也有点困难——我试着做一些类似 props.language 的事情——但那是一个错误,因为那时它是只读状态。
  • 我已将您的代码添加到项目中——但它看起来像 props.language 始终未定义——而且当点击链接时——它永远不会再次调用构造函数,所以这个。语言我不认为 props.language 有利于 - 老实说 - 看起来 props.language 总是从未设置?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多