在 redux state 的语言环境更新后重新渲染 React 组件
Rerendering React components after redux state's locale has updated
我已经在我的 React
应用程序中实现了 Redux
,到目前为止效果很好,但我有一个小问题。
我的导航栏中有一个选项可以更改存储在 redux's state
中的 locale
。当我更改它时,我希望每个组件都重新呈现以更改翻译。为此,我必须指定
locale: state.locale
在mapStateToProps
函数中...导致大量代码重复。
有没有办法将语言环境隐式传递到每个组件的 props connect
ed with react-redux
?
提前致谢!
为了减少代码重复,我通常在将状态映射到 props 时将箭头函数传递给 connect 方法,这对我来说看起来更干净。不幸的是,我认为没有另一种方法可以使其隐式化,因为您的组件可以订阅多个商店 "objects".
export default connect((state) => ({
local: state.locale
}))(component);
为了解决这个问题,你可以设置你的父组件的Context,然后在你的子组件中使用它。这就是 Redux 用来为连接的 React 组件提供商店的 state
和 dispatch
功能的东西。
在您的父组件中,实现 getChildContext
并指定每个变量的 PropType
。
class Parent extends React.Component {
getChildContext() {
return {
test: 'foo'
};
}
render() {
return (
<div>
<Child />
<Child />
</div>
);
}
}
Parent.childContextTypes = {
test: React.PropTypes.string
};
在您的子组件中,使用 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
};
这里有一个 demo 可以正常工作。
我不妨提一下,虽然像 Redux 这样的库使用这个,但 React 的文档指出这是一个高级和实验性的功能,并且可能 changed/removed 在未来的版本中。我个人不会推荐这种方法,而不是像您最初提到的那样简单地在 mapStateToProps
中传递您需要的信息。
Redux 实现了一个 shouldComponentUpdate 来防止组件更新,除非它的 props 被更改。
在您的情况下,您可以通过将 pure=false
传递给 connect
来忽略此检查:
connect(select, undefined, undefined, { pure: false })(NavBar);
出于性能原因,这是一件好事,但可能不是您想要的。
相反,我建议编写一个自定义连接函数,以确保 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 }
我已经在我的 React
应用程序中实现了 Redux
,到目前为止效果很好,但我有一个小问题。
我的导航栏中有一个选项可以更改存储在 redux's state
中的 locale
。当我更改它时,我希望每个组件都重新呈现以更改翻译。为此,我必须指定
locale: state.locale
在mapStateToProps
函数中...导致大量代码重复。
有没有办法将语言环境隐式传递到每个组件的 props connect
ed with react-redux
?
提前致谢!
为了减少代码重复,我通常在将状态映射到 props 时将箭头函数传递给 connect 方法,这对我来说看起来更干净。不幸的是,我认为没有另一种方法可以使其隐式化,因为您的组件可以订阅多个商店 "objects".
export default connect((state) => ({
local: state.locale
}))(component);
为了解决这个问题,你可以设置你的父组件的Context,然后在你的子组件中使用它。这就是 Redux 用来为连接的 React 组件提供商店的 state
和 dispatch
功能的东西。
在您的父组件中,实现 getChildContext
并指定每个变量的 PropType
。
class Parent extends React.Component {
getChildContext() {
return {
test: 'foo'
};
}
render() {
return (
<div>
<Child />
<Child />
</div>
);
}
}
Parent.childContextTypes = {
test: React.PropTypes.string
};
在您的子组件中,使用 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
};
这里有一个 demo 可以正常工作。
我不妨提一下,虽然像 Redux 这样的库使用这个,但 React 的文档指出这是一个高级和实验性的功能,并且可能 changed/removed 在未来的版本中。我个人不会推荐这种方法,而不是像您最初提到的那样简单地在 mapStateToProps
中传递您需要的信息。
Redux 实现了一个 shouldComponentUpdate 来防止组件更新,除非它的 props 被更改。
在您的情况下,您可以通过将 pure=false
传递给 connect
来忽略此检查:
connect(select, undefined, undefined, { pure: false })(NavBar);
出于性能原因,这是一件好事,但可能不是您想要的。
相反,我建议编写一个自定义连接函数,以确保 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 }