我写了一些HOC,我需要将在某个生命周期级别上创建的动态对象传递给此HOC,但我没有把他当作道具。 如果我尝试传递一些静态值(例如,从开始初始化myObj),它将按预期工作,并且我得到正确的值。
让我们说这是我的组件类:
let myObj = {};
class Test extends React.Component
{
constructor(props) {
super(props);
.....
}
render() {
myObj = {test:'test'};
return ( ... )
}
}
export default withHOC(Test, myObj);
这是我的HOC:
const withHOC = (Component, test) => {
class Hoc extends React.Component
{
constructor(props)
{
super(props);
const s = test; // ---->test is empty object always !!
...
}
}
return Hoc;
}
我在“测试”类上创建的“动态”对象在HOC类上始终为空。 当我尝试直接从道具传递一些值时也会发生这种情况,在这种情况下,页面会卡住(控制台中没有错误)。
有人知道如何解决吗?谢谢!
答案 0 :(得分:1)
以这种方式组合组件时,组合仅在编译时发生(静态组合)。这意味着withHOC仅运行一次,并且接收到空的myObj
参数,因为它使用的是声明中定义的参数。
export default withHOC(Test, myObj); //myObj = {}
如果您希望该值是动态的,则应在该值更改时运行withHOC
组合。
您无法将数据从WrappedComponent
(测试)发送到HOC
(withHOC),因此,即使您在myObj
中更改了Test.render
的值, HOC永远不会知道。
如果确实需要,您可以做的是Test.render
render(){
const Hoc = withHOC(this.state.myObj, WrappedComponent);//WrappedComponent can be anything
return(
<Hoc/>
)
}
这样,每次组件渲染时,Hoc
都使用来自组件状态的值作为myObj
来组成,这不是最好的方式,因为this.state.myObj可能具有与上一个渲染相同的值,并且您将使用与以前相同的数据重新组成。
一种更好的方法是在Test.componentDidUpdate
处检查myObj中的更改,如果更改了,请再次编写Hoc
。
答案 1 :(得分:0)
您要将空对象传递给withHOC
函数
let myObj = {}; // <- your myObj is empty
class Test extends React.Component
{
constructor(props) {
super(props);
.....
}
render() {
myObj = {test:'test'}; // <- You're doing this in the render method of your Test component, so until the component is rendered myObj is empty
return ( ... )
}
}
export default withHOC(Test, myObj);
答案 2 :(得分:0)
按顺序对此处发生的情况进行了一些解释:
import Comp from '.../Test.js'
withHOC
(在调用上方定义)和Test
(在调用上方定义但为空)的参数触发myObj
函数。myObj = {test:'test'}
的逻辑建议的解决方案: 使得HOC可以从道具中获得逻辑:
const withProps = newProps => BaseComponent => props => {
const propsToAdd = typeof newProps === 'function' ? newProps(props) : newProps
return <BaseComponent {...props} {...propsToAdd} />
}
用法:
class Test extends React.Component
{
constructor(props) {
super(props);
.....
}
render() {
return ( ... )
}
}
export default withProps({test:'test'})(withHOC(Test));
// or: export default withProps(props => {test:'test'})(withHOC(Test));
const withHOC = (Component) => {
class Hoc extends React.Component
{
constructor(props)
{
super(props);
const s = this.props.test;
...
}
}
return Hoc;
}
您可以使用recompose,这是一个具有很多hoc和utils,并具有更好的可读性的库:
import { compose, withProps } from "recompose"
class Test extends React.Component {...}
const enhance = compose(
withProps({test:'test'}),
withHOC
)
export default enhance(Test);
答案 3 :(得分:0)
我不能肯定地说这是最佳选择,但是我通过在HOC中拥有一个更新状态的函数来解决了类似的问题,然后可以使用包装的组件中的任何数据来调用状态。
HOC:
func = (a, b) => {
this.setState({
stateA: a,
stateB: b
)}
}
return ({ <WrappedComponent func={this.func} /> })
包装组件:
this.props.func(anythingA, anythingB);
然后您可以通过HOC中的状态访问数据。
详细说明:
const withHOC = (WrappedComponent) => {
class withHOC extends React.Component {
constructor(props) {
super(props)
this.state = {
stateA: 1,
stateB: 2
}
*use state however you want in this HOC, including pass it through to another component*
*the following is just a function*
*when it's invoked in the wrapped component state will update here in the
HOC*
changeState = (a, b) => {
this.setState({
stateA: a,
stateB: b
)}
}
render() {
return (
<div>
<p>this.state.stateA</p>
<p>this.state.stateB</p>
<WrappedComponent changeState={this.changeState} />
</div>
)
}
}
}
}
在导入后,在wrappedComponent中:
class aComponent extends Component {
constructor(props) {
super(props)
this.state = {
}
*you can now invoke the function from the HOC in this wrapped component*
}
}
答案 4 :(得分:0)
您可以使用react-redux并将对象存储为redux状态。随时随地更改对象(在情况下为Test),并从redux状态访问HOC内部组件中的对象,该对象将始终保持最新状态。