使用钩子的React组件不能基于类;它们必须以功能为基础。我曾经在基于类的组件中做过一些事情,但我不知道如何在基于函数的组件中完成:调用子组件上的方法。
对我来说,这是在像地图或photoshop文档一样的组件中出现的。它们通常有一种缩放到特定区域的方法,同时也允许用户在之后自由平移。
可以设计这样一个<Zoomable>
组件来保持其缩放到的内部状态,但提供一个公共方法zoomTo(place)
。
可以像这样使用缩放组件:
const ZoomableUI = ({place}) => {
const zoomable = React.useRef(null)
React.useEffect(() => {
zoomable.zoomTo(place)
}, [place])
return (
<div>
<Zoomable ref={zoomable} />
<button onClick={() => zoomable.current.zoomTo(place)}>
Re-Center
</button>
</div>
)
}
该组件可使Zoomable在首次渲染时或place
属性更改时缩放到某个位置,但用户可以在之后自由平移。然后,他们可以通过单击按钮将其重新定位在当前位置。
当然,如果Zoomable是作为一个基于函数的组件实现的,那么这些都不起作用。您将如何使用基于函数的映射来实现这种系统?
当您切换到基于函数的React组件时,提供公共方法的替代方案是什么?
顺便说一句,不要建议我把按钮放在缩放框里。它的目的是作为一个行为示例,这些行为可能来自应用程序中的任何地方,而不一定位于DOM中的某个位置。
您可以将Zoomable变成一个完全受控的组件。然后,父组件将需要管理其缩放级别和位置。
const ZoomableUI = ({place}) => {
const [mapState, setMapState] = React.useState(place)
React.useEffect(() => {
setMapState(place)
}, [place])
return (
<div>
<Zoomable state={mapState} setState={setMapState} />
<button onClick={() => setMapState(place)}>
Re-Center
</button>
</div>
)
}
我看到的另一种可能性是把这个地方当作道具。Zoomable可以有一个内部useEffect
,当位置发生变化时,它会将其缩放到该位置。但这对按钮不起作用,因为按钮不会改变道具。我可以在Zoomable的key
道具中放置一个计数器,使其刷新状态。
const ZoomableUI = ({place}) => {
const [counter, setCounter] = React.useState(0)
return (
<div>
<Zoomable place={place} key={counter} />
<button onClick={() => setCounter((counter) => counter + 1)}>
Re-Center
</button>
</div>
)
}