简体   繁体   English

当上下文更改时,使用上下文的子组件是否应该自动更新?

[英]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.jsxLocalizedComponent实现为类,但是我注意到当状态更改时, 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.

相关问题 呈现子组件时无法设置上下文 - Unable to set context when rendering child components 更改画布宽度/高度时,画布上下文会重置 - canvas context gets reset when canvas width/height are changed React context api 仅呈现使用已更改值的组件 - React context api only render components that use values that have changed 为什么当上下文值更新时我的上下文没有更新? - why my context doesn't update when the context value updates? 使用上下文api和HOC不会为不同组件更新状态 - The state doesn't update for different components using context api and HOC 当提供程序组件父状态更改时,为什么无法更新子组件中的值(使用react上下文)? - Why can't update a value in a child component (with react context) when a provider component parent state change? 子代反应组件中的易变上下文和executeAction - Fluxible context and executeAction in child react components 是否在子组件之前安装了React上下文提供程序? - Is React context provider not mounted before child components? 从子组件向 React 上下文添加值 - Add value to React context from child components 如何使用父级(类组件)的上下文值更新子组件中的 state - How to update state in child component with context value from parent (class components)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM