Javascript 不应该';当上下文发生变化时,使用上下文的子组件会自动更新自己吗?

Javascript 不应该';当上下文发生变化时,使用上下文的子组件会自动更新自己吗?,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我正在尝试创建一个本地化解决方案 出于测试目的,我有以下结构 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 ( <Provide

我正在尝试创建一个本地化解决方案

出于测试目的,我有以下结构

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'));
一个
组件可以是这样的

Home.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;
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;
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;
从“React”导入React;
功能组件(道具){
返回(
{道具}

); } SomeComponent.propTypes={ :React.PropTypes.string }; SomeComponent.defaultProps={ : '' }; 导出默认组件;
为了把所有这些结合在一起,我们这样做

HomeContainer.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;
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;
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;
从“组件/呈现/主页”导入主页;
从“组件/HOC/本地化”导入翻译;
常量mapTranslationToProps=(字符串,语言)=>({
:字符串。[语言]
});
LocalizedComponent=翻译(mapTranslationToProps)(SomeComponent);
导出默认本地化组件;
第一次呈现时,通过
上下文
从状态中选择正确的
语言
,并相应地显示文本

但是,当我分派一个操作来更改状态中的
语言时,组件不会得到更新

我的印象是,在适用的情况下,对上下文的更改会触发重新渲染,但似乎情况并非如此

我尝试将
LocalizedComponent
作为一个类在
localization.jsx
中实现,并使用生命周期方法,但是我注意到
shouldComponentUpdate
在状态更改时甚至不会触发

我希望当所选语言更改时,
LocalizedComponent
s自动更新。显然我一定做错了什么


有人能帮我理解什么吗?

如果您使用
React Redux
您应该使用方法将组件连接到Redux存储。
更新
context
值不会触发组件重新呈现-当
context
中的任何内容发生更改时,不会通知React组件。仅当React组件的状态已更改、其父组件已重新呈现或已被调用时,才会重新呈现该组件。本例中的上下文只指向充当redux存储的对象,而React组件不知道该对象中的更改。 此外,您不应该更新上下文。根据react:

不要这样做

React有一个用于更新上下文的API,但它从根本上被破坏了 你不应该使用它

此外,在React Redux中,上下文存储属性始终指向同一存储对象-当状态更新时,只有一些内部存储对象属性发生更改,但上下文仍保留相同的对象引用,因此实际上上下文值不会更改

有两种解决方案可确保组件在调度操作后redux状态发生更改时得到通知和更新

如果使用React-Redux,则应使用React-Redux。根据文档
connect
返回:

传递状态和动作的高阶React组件类 从提供的参数派生的组件的创建者

当给定组件使用的状态属性发生更改时,连接到存储的组件将自动重新呈现

如果不使用React Redux,还可以使用Redux存储方法手动订阅存储更新。根据文档
订阅

添加更改侦听器。它将在任何时候调用一个操作 已调度,并且状态树的某些部分可能具有 改变。然后可以调用getState()来读取当前状态树 在回调函数内部


如果使用
React Redux
,则应使用方法将组件连接到Redux存储。
更新
context
值不会触发组件重新呈现-当
context
中的任何内容发生更改时,不会通知React组件。仅当React组件的状态已更改、其父组件已重新呈现或已被调用时,才会重新呈现该组件。本例中的上下文只指向充当redux存储的对象,而React组件不知道该对象中的更改。 此外,您不应该更新上下文。根据react:

不要这样做

React有一个用于更新上下文的API,但它从根本上被破坏了 你不应该使用它

此外,在React Redux中,上下文存储属性始终指向同一存储对象-当状态更新时,只有一些内部存储对象属性发生更改,但上下文仍保留相同的对象引用,因此实际上上下文值不会更改

有两种解决方案可确保组件在调度操作后redux状态发生更改时得到通知和更新

如果使用React-Redux,则应使用React-Redux。根据文档
connect
返回:

传递状态和动作的高阶React组件类 从提供的参数派生的组件的创建者

当给定组件使用的状态属性发生更改时,连接到存储的组件将自动重新呈现

如果不使用React Redux,还可以使用Redux存储方法手动订阅存储更新。根据文档
订阅

添加更改侦听器。它将在任何时候调用一个操作 已调度,并且状态树的某些部分可能具有 改变。然后可以调用getState()来读取当前状态树 在回调函数内部


如何设置上下文?如果您使用上下文,您应该在充当上下文提供程序的组件上定义
getChildContext
方法,但我在代码中看不到它。我正在通过
react redux
传递上下文。因为它包装了整个应用程序,所以上下文对任何要求它的孩子都是可用的