简体   繁体   English

在redux状态的语言环境更新后重新呈现React组件

[英]Rerendering React components after redux state's locale has updated

I've implemented Redux in my React application, and so far this is working great, but I have a little question. 我在我的React应用程序中实现了Redux ,到目前为止这个工作很好,但我有一个小问题。

I have an option in my navbar to change the locale , stored in redux's state . 我在导航栏中有一个选项可以更改存储在redux's statelocale When I change it, I expect every component to rerender to change traductions. 当我改变它时,我希望每个组件都能重新发布以改变转换。 To do this, I have to specify 要做到这一点,我必须指定

locale: state.locale

in the mapStateToProps function... Which leads to a lot of code duplication. mapStateToProps函数中...这导致了大量的代码重复。

Is there a way to implicitly pass locale into the props of every component connect ed with react-redux ? 有没有办法隐式地将locale传递react-redux connect的每个组件的道具?

Thanks in advance! 提前致谢!

Redux implements a shouldComponentUpdate that prevents a component from updating unless it's props are changed. Redux实现了一个shouldComponentUpdate ,它可以防止组件更新,除非它的props被更改。

In your case you could ignore this check by passing pure=false to connect : 在您的情况下,您可以通过将pure=false传递给connect来忽略此检查:

connect(select, undefined, undefined, { pure: false })(NavBar);

For performance reasons this is a good thing and probably isn't what you want. 出于性能原因,这是一件好事,可能不是你想要的。

Instead I would suggest writing a custom connect function that will ensure locale is always added to your component props: 相反,我建议编写一个自定义连接函数,以确保locale始终添加到组件道具:

const localeConnect = (select, ...connectArgs) => {
  return connect((state, ownProps) => {
    return {
      ...select(state, ownProps),
      locale: state.locale
    };
  }, ...connectArgs);
};

// Simply use `localeConnect` where you would normally use `connect`
const select = (state) => ({ someState: state.someState });

localeConnect(select)(NavBar);  // props = { someState, locale }

To cut down the duplication of code I usually just pass an arrow function to the connect method when mapping state to props, looks cleaner to me. 为了减少代码的重复,我通常只是在将状态映射到props时将箭头函数传递给connect方法,对我来说看起来更干净。 Unfortunately though, I don't think there is another way to make it implicit as your component could subscribe to multiple store "objects". 不幸的是,我不认为还有另一种方法可以使它隐含,因为您的组件可以订阅多个商店“对象”。

export default connect((state) => ({
  local: state.locale
}))(component);

To solve this problem, you can set the Context of your parent component, and use it in your child components. 要解决此问题,您可以设置父组件的上下文 ,并在子组件中使用它。 This is what Redux uses to supply the store's state and dispatch function to connected React components. 这是Redux用于向连接的React组件提供商店的statedispatch功能的方法。

In your Parent component, implement getChildContext and specify each variable's PropType . 在Parent组件中,实现getChildContext并指定每个变量的PropType

class Parent extends React.Component {
    getChildContext() {
        return {
            test: 'foo'
        };
    }

    render() {
        return (
            <div>
                <Child />
                <Child />
            </div>
        );
    }

}

Parent.childContextTypes = {
    test: React.PropTypes.string
};

In your Child component, use this.context.test and specify its PropType . 在您的Child组件中,使用this.context.test并指定其PropType

class Child extends React.Component {
    render() {
        return (
            <div>
                <span>Child - Context: {this.context.test}</span>
            </div>
        );
    }
}

Child.contextTypes = {
    test: React.PropTypes.string
};

Here's a demo of it working. 这是一个工作的演示

I might as well mention that, while libraries like Redux use this, React's documentation states that this is an advanced and experimental feature, and may be changed/removed in future releases. 我不妨提一下,虽然像Redux这样的库使用它,但React的文档说明这是一个高级的实验性功能,可能会在将来的版本中更改/删除。 I personally would not recommend this approach instead of simply passing the information you need in mapStateToProps , like you originally mentioned. 我个人不会推荐这种方法,而不是简单地传递mapStateToProps所需的信息,就像你最初提到的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM