ReactJS中如何根据子视图组件类型控制Rotate按钮显隐
解决React路由视图切换时控制按钮可见性的问题
你可以通过两种方式来实现根据当前路由视图更新isViewType1状态,从而控制Rotate按钮的显示:
方法一:在Route的render函数中更新状态
在每个路由的render回调里,判断当前状态是否需要更新,再调用你的setRotateButtonVisibility方法。这样每次路由匹配时都会同步更新状态,避免无效的重复渲染:
class ParentView extends Component { constructor(props) { super(props); this.state = { isViewType1: true }; this.setRotateButtonVisibility = this.setRotateButtonVisibility.bind(this); } setRotateButtonVisibility(isType1) { this.setState({ isViewType1: isType1 }); } render() { return ( <> {/* 只有isViewType1为true时显示按钮 */} {this.state.isViewType1 && ( <button id="btnRotate" className="btn btn-default">Rotate</button> )} <Switch> <Route exact path="/project/:projectID" render={() => { // 仅当当前状态不是true时才更新,避免重复渲染 if (!this.state.isViewType1) { this.setRotateButtonVisibility(true); } return <Viewtype1 />; }} /> <Route exact path="/project/:projectID/ukeyview" render={() => { if (this.state.isViewType1) { this.setRotateButtonVisibility(false); } return <Viewtype2 />; }} /> <Route exact path="/project/:projectID/proxystructureview" render={() => { if (this.state.isViewType1) { this.setRotateButtonVisibility(false); } return <Viewtype3 />; }} /> </Switch> </> ); } }
方法二:监听路由变化(更优雅的方式)
使用react-router-dom的withRouter高阶组件,让父组件能访问路由信息,然后在组件生命周期中监听路径变化,统一更新状态:
import { withRouter, Switch, Route } from 'react-router-dom'; class ParentView extends Component { constructor(props) { super(props); this.state = { isViewType1: true }; this.updateRotateButtonVisibility = this.updateRotateButtonVisibility.bind(this); } componentDidMount() { // 初始化时检查当前路径 this.updateRotateButtonVisibility(this.props.location.pathname); } componentDidUpdate(prevProps) { // 当路径变化时更新状态 if (prevProps.location.pathname !== this.props.location.pathname) { this.updateRotateButtonVisibility(this.props.location.pathname); } } updateRotateButtonVisibility(pathname) { // 判断当前路径是否对应ViewType1 const isType1 = pathname.match(/^\/project\/[^/]+$/) !== null; this.setState({ isViewType1: isType1 }); } render() { return ( <> {this.state.isViewType1 && ( <button id="btnRotate" className="btn btn-default">Rotate</button> )} <Switch> <Route exact path="/project/:projectID" render={() => <Viewtype1 />} /> <Route exact path="/project/:projectID/ukeyview" render={() => <Viewtype2 />} /> <Route exact path="/project/:projectID/proxystructureview" render={() => <Viewtype3 />} /> </Switch> </> ); } } // 用withRouter包裹组件,使其能访问location等路由props export default withRouter(ParentView);
为什么你之前的尝试没生效?
- 你在Route里直接写
{...this.setRotateButtonVisibility(false)}的方式是错误的:这种写法会在组件每次渲染时立即执行该函数,而setState会触发重渲染,进而导致无限循环,而且这并不是路由匹配时的正确回调方式。 - 子组件回调没生效可能是因为你没有正确将回调函数通过props传递给子组件,或者没有在合适的生命周期(比如
componentDidMount)里调用它。
内容的提问来源于stack exchange,提问作者Mehul Patel
相关产品推荐
相关产品推荐

