在Hook版本中使用WrappedComponent的React HOC总是重新启动状态。

问题描述 投票:0回答:1

我有一个HOC,目前我想把它改造成Hook版本,但我发现它总是呈现出

让我们看看这个例子。

const f = ()=> { console.log("init"); return "";}
const hoc = ({someProp = ""}) => WrappedComponent => {
   const HOC = ({...props}) => {
       const [selected, setSelected] = useState(f());
       return <WrappedComponent {...props} setSelected={setSelected}/>
   }
   return HOC;
}

当WrappedComponent中的setSelected触发时,f()将始终被调用。

让我们看看另一个例子。

const f = ()=> { console.log("init"); return "";}
const hoc = ({someProp = ""}) => WrappedComponent => {
   class HOC extends Component {
         constructor(props) {
            super(props);
            this.state = {selected: f()}
            this.setSelected = this.setSelected.bind(this);
         }
         setSelected(value) {
            this.setState({selected:value})
        }
        render() {
           return <WrappedComponent {...props} setSelected={this.setSelected}/>

        }
  }

  return HOC;
}

f()只会调用一次

如果我必须使用Hoc Format,但又想让Hoc本身成为一个功能组件,我该如何解决这种情况?

或者我只是改变

const [selected, setSelected] = useState(f()); 

const [selected, setSelected] = useState(() => f());
reactjs hook
1个回答
1
投票

你误用了 useState.

每次HOC渲染。f() 会被调用。

让我在这里啰嗦一下,也许下面的代码会让你看得更清楚。

const hoc = ({someProp = ""}) => WrappedComponent => {
   const HOC = ({...props}) => {
       const state = f(); // Sure, this line would be executed every time.
       const [selected, setSelected] = useState(state);
       ...
   }
  ...
}

我猜你是想执行 f() 来在初始化Component时获得init状态,然后让Component自己处理状态,不过不推荐这样做。

对于这种情况,我更倾向于采用以下方法之一。

  1. f() 从母体到HOC组件

    这是在创建HOC的同时生成init状态的最简单的方法。

  2. 使用 useEffect 如果第一次渲染时是空白状态就可以了。

    你可以认为 useEffect 如旧 didMount 生命周期API。


0
投票

答案是改变

const [selected, setSelected] = useState(f())。

const [selected, setSelected] = useState(() => f())。

而f()无论渲染多少次,都只会调用一次,除了unmount

© www.soinside.com 2019 - 2024. All rights reserved.