6

我写了一些 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 类上始终为空。当我尝试直接从我的道具传递一些值时也会发生这种情况,在这种情况下页面被卡住(控制台中没有错误)。

有人知道如何解决这个问题吗?谢谢!

4

5 回答 5

5

当您以这种方式组合组件时,组合只发生在编译时(静态组合)。这意味着 withHOC 只运行一次并且接收一个空myObj参数,因为它使用的是在声明中定义的参数。

export default withHOC(Test, myObj); //myObj = {}

如果您希望该值是动态的,withHOC则应在该值更改时运行组合。

您无法将数据从WrappedComponent(Test) 发送到HOC(withHOC),因此即使您更改中的myObjTest.render,HOC 也永远不会知道。

如果你真的需要的话,你能做的就是在Test.render

render(){
    const Hoc = withHOC(this.state.myObj, WrappedComponent);//WrappedComponent can be anything
    return(
        <Hoc/>
    )
}

这样,每次组件渲染时,Hoc都使用myObj组件状态中的值来组合,这不是最好的方法,因为 this.state.myObj 可能具有与前一次渲染时相同的值,并且您将使用与以前相同的数据重新组合。

更好的方法是检查 myObj at 中的更改Test.componentDidUpdate,如果确实发生了更改,则Hoc再次编写。

于 2019-11-02T06:01:11.037 回答
0

我不能自信地说这是最优的,但我通过在 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*
  }
}




于 2019-09-23T14:03:41.660 回答
0

您可以使用 react-redux 并将您的对象存储在 redux 状态。在您需要的任何地方更改对象(在您的情况下它在测试中)并在您的 HOC 内部的组件中从 redux 状态访问它,它将始终是最新的。

于 2020-11-02T14:37:21.067 回答
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);
于 2019-03-14T12:50:41.663 回答
0

关于这里发生的事情的一些解释,按顺序:

  1. import Comp from '.../Test.js'
  2. withHOC函数被触发,参数为Test(在调用上方定义)和myObj(在调用上方定义但为空)
  3. 测试组件返回,没有人使用逻辑myObj = {test:'test'}

建议的解决方案:让 HOC 从另一个 hoc 的 props 中获取逻辑:

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,这是一个包含许多 hocs 和 utils 的库,并且为了更好的可读性:

import { compose, withProps } from "recompose"

class Test extends React.Component {...}

const enhance = compose(
  withProps({test:'test'}),
  withHOC
)
export default enhance(Test);
于 2019-04-02T06:30:44.437 回答