[英]Shouldn't child components that use context update themselves automatically when context gets changed?
I am trying to create a localization solution. 我正在尝试创建一个本地化解决方案。
I am having the following structure for test purposes 我具有以下结构用于测试
index.js 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'));
The HomeContainer component is a HOC that wraps a simple presentational component into a localization component. HomeContainer组件是一个HOC,它将简单的演示组件包装到本地化组件中。
localization.jsx 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
is a function such as this mapper
是这样的功能
const mapTranslationToProps = (strings, language) => ({
<property key>: strings.<some key>[language]
});
and a Component
could be something like this 一个
Component
可能是这样的
Home.jsx 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;
in order to bring all these together we do this 为了将所有这些整合在一起
HomeContainer.jsx 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;
The first time this gets rendered, the correct language
is picked from the state, via context
and the text is displayed accordingly 第一次渲染时,会通过
context
从状态中选择正确的language
,并相应地显示文本
However when I dispatch an action that changes the language
in the state, the component does not get updated. 但是,当我分派操作以更改状态
language
时,该组件不会得到更新。
I was under the impression that changes to context would trigger a re-rendering, where applicable, but it seems that this isn't so. 我的印象是,对上下文的更改将在适用的情况下触发重新渲染,但事实并非如此。
I tried implementing the LocalizedComponent
inside localization.jsx
as a class, with lifecycle methods, but I noticed that shouldComponentUpdate
does not even fire when the state changes. 我尝试使用生命周期方法将
localization.jsx
的LocalizedComponent
实现为类,但是我注意到当状态更改时, shouldComponentUpdate
甚至不会触发。
I want LocalizedComponent
s to update automatically when the selected language changes. 我希望
LocalizedComponent
在所选语言更改时自动更新。 Apparently I must be doing something wrong. 显然我一定做错了。
Can someone help me understand what? 有人可以帮助我了解什么吗?
If you use React-Redux
you should use connect method to connect your components to redux store. 如果使用
React-Redux
,则应使用connect方法将组件连接到redux存储。
Updating context
values doesn't trigger components re-render - React components are not notified when anything in context
has changed. 更新
context
值不会触发组件的重新渲染-当context
中的任何内容发生更改时,不会通知React组件。 React component is re-rendered only if its state has changed, its parent has been re-rendered or forceUpdate has been called. 仅当状态已更改,其父级已被重新渲染或已调用forceUpdate时 ,才重新渲染React组件。 Context in your case just points to an object that acts as redux store and React components are not aware of changes in this object.
在您的情况下,上下文仅指向充当Redux存储的对象,并且React组件不知道此对象中的更改。 Besides, you should never update context.
此外,您永远不要更新上下文。 According to react docs :
根据react docs :
Don't do it.
不要这样
React has an API to update context, but it is fundamentally broken and you should not use it.
React拥有一个用于更新上下文的API,但从根本上讲它已损坏,您不应使用它。
Furthermore, in React-Redux context store property always points to the same store object - when state is updated only some internal store object properties are changed but context still holds the same object reference so actually context value doesn't change. 此外,在React-Redux上下文中,存储属性始终指向相同的存储对象-更新状态时,仅会更改一些内部存储对象属性,但上下文仍持有相同的对象引用,因此实际上下文值不会更改。
There are two solutions to make sure your components are notified and updated when redux state has changed after dispatching an action. 有两种解决方案可确保在分派操作后,当redux状态发生更改时,通知并更新您的组件。
If you use React-Redux you should use React-Redux connect . 如果您使用React-Redux,则应该使用React-Redux connect 。 According to docs
connect
returns: 根据文档
connect
返回:
A higher-order React component class that passes state and action creators into your component derived from the supplied arguments.
一个高阶React组件类,该类将状态和动作创建者从提供的参数派生到您的组件中。
Components connected to store will be automatically re-rendered when state properties used by given component has changed. 当给定组件使用的状态属性发生更改时,连接到存储的组件将自动重新呈现。
If you don't use React-Redux you can also manually subscribe to store updates using Redux store subscribe method. 如果您不使用React-Redux,您还可以使用Redux store subscription方法手动订阅存储更新。 According to docs
subscribe
: 根据文档
subscribe
:
Adds a change listener.
添加更改侦听器。 It will be called any time an action is dispatched, and some part of the state tree may potentially have changed.
每当分派动作时,就会调用它,并且状态树的某些部分可能已更改。 You may then call getState() to read the current state tree inside the callback.
然后,您可以调用getState()以读取回调中的当前状态树。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.