我正在尝试创建本地化解决方案。
我有以下结构用于测试目的
index.js
import { Provider } from 'react-redux';
import store from './store'; //This is a redux store
import LocalizedComponent from './components/containers/HomeContainer';
function App() {
return (
<Provider store={store}>
<LocalizedComponent />
</Provider>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
HomeContainer组件是一个HOC,它将简单的表示组件包装到本地化组件中。
localization.jsx
import React, { PropTypes } from 'react';
import STRINGS from 'strings'; //This is an object containing translations
const translate = mapper => (Component) => {
function LocalizedComponent(props, { store }) {
const language = store.getState().language;
const translatedProps = mapper(STRINGS, language);
return (
<Component {...props} {...translatedProps} />
);
}
LocalizedComponent.contextTypes = {
store: React.PropTypes.object
};
return LocalizedComponent;
};
export default translate;
mapper
是一个像
const mapTranslationToProps = (strings, language) => ({
<property key>: strings.<some key>[language]
});
和Component
可能是这样的
Home.jsx
import React from 'react';
function SomeComponent(props) {
return (
<div>
<p>{props.<property key>}</p>
</div>
);
}
SomeComponent.propTypes = {
<property key>: React.PropTypes.string
};
SomeComponent.defaultProps = {
<property key>: ''
};
export default SomeComponent;
为了将所有这些结合起来,我们这样做
HomeContainer.jsx
import Home from 'components/presentational/Home';
import translate from 'components/HOC/Localization';
const mapTranslationToProps = (strings, language) => ({
<property key>: strings.<some key>[language]
});
LocalizedComponent = translate(mapTranslationToProps)(SomeComponent);
export default LocalizedComponent;
第一次渲染时,通过language
从状态中选择正确的context
,并相应地显示文本
但是,当我发送一个更改状态language
的操作时,组件不会更新。
我的印象是,在适用的情况下,对上下文的更改会触发重新呈现,但似乎并非如此。
我尝试使用生命周期方法在LocalizedComponent
内部实现localization.jsx
作为类,但我注意到shouldComponentUpdate
在状态发生变化时甚至不会触发。
我希望LocalizedComponent
在所选语言发生变化时自动更新。显然我一定是做错了。
有人可以帮我理解吗?
答案 0 :(得分:2)
如果您使用React-Redux
,则应使用connect方法将组件连接到redux商店。
更新context
值不会触发重新呈现的组件 - 当context
中的任何内容发生更改时,不会通知React组件。仅当React组件的状态已更改,其父级已重新呈现或已调用forceUpdate时,才会重新呈现React组件。在您的情况下,上下文仅指向充当redux存储的对象,并且React组件不知道此对象中的更改。
此外,你永远不应该更新上下文。根据反应docs:
不要这样做。
React有一个API来更新上下文,但它从根本上被打破了 你不应该使用它。
此外,在React-Redux上下文存储属性始终指向同一个商店对象 - 当状态更新时,只更改了一些内部存储对象属性,但上下文仍保持相同的对象引用,因此实际上下文值不会更改
在调度操作后,当redux状态发生变化时,有两种解决方案可以确保通知和更新组件。
如果您使用React-Redux,则应使用React-Redux connect。根据文档connect
返回:
传递状态和操作的高阶React组件类 从提供的参数派生到组件中的创建者。
当给定组件使用的状态属性发生更改时,将自动重新呈现连接到存储的组件。
如果您不使用React-Redux,您还可以使用Redux store subscribe方法手动订阅商店更新。根据文档subscribe
:
添加更改侦听器。它会在任何时候被调用 调度,状态树的某些部分可能有 改变。然后,您可以调用getState()来读取当前状态树 在回调中。