使用道具传递 _setTitle 方法是不是可行?

Posted

技术标签:

【中文标题】使用道具传递 _setTitle 方法是不是可行?【英文标题】:Is passing the _setTitle method with the props the way to go?使用道具传递 _setTitle 方法是否可行? 【发布时间】:2019-04-07 21:05:56 【问题描述】:

想要更新 Header 中的标题 每次我们导航到新页面。 使用道具传递 _setTitle 方法是否可行?

import React,  Component  from 'react';
import PropTypes from 'prop-types';

主应用组件

export class App extends Component 
  constructor() 
    super();

    this.state =  pageTitle: 'My app' ;
    this._setTitle = this._setTitle.bind(this);
  

  _setTitle(title) 
    this.setState( pageTitle: title );
  

  render() 
    const  pageTitle  = this.state.pageTitle;

    return (
      <div>
        <Header title=pageTitle />
        React.cloneElement(children,  setTitle: this._setTitle )
        <Footer />
      </div>
    );
  

页眉和页脚组件

export class Header extends Component 
  static propTypes = 
    title: PropTypes.string
  ;
  // ...
  render() 
    const  title  = this.props;

    return <h2>title</h2>;
  



export class Footer extends Component 
  // Footer code

以下是不同的页面组件:

export class Profile extends Component 
  static propTypes = 
    setTitle: PropTypes.func.isRequired
  ;
  componentWillMount() 
    this.props.setTitle('Profile');
  



export class Projects extends Component 
  static propTypes = 
    setTitle: PropTypes.func.isRequired
  ;
  componentWillMount() 
    this.props.setTitle('Projects');
  
  // ...



export class ProjectForm extends Component 
  static propTypes = 
    setTitle: PropTypes.func.isRequired
  ;
  componentWillMount() 
    this.props.setTitle('New Project');
  
  // ...



export class Translators extends Component 
  static propTypes = 
    setTitle: PropTypes.func.isRequired
  ;
  componentWillMount() 
    this.props.setTitle('Translators');
  
  // ...


// ...

我该如何改进这一点。我是新手,所以请建议如果您有任何想法,我会实施它。谢谢。

【问题讨论】:

【参考方案1】:

你可以利用 Context 并将 setTitle 方法作为 Context 值传递,然后你可以创建一个具有设置 Title 逻辑的组件,一个简单的实现如下所示

const TitleContext = React.createContext();

export class App extends Component 
  constructor() 
    super();

    this.state =  pageTitle: 'My app' ;
    this._setTitle = this._setTitle.bind(this);
  

  _setTitle(title) 
    this.setState( pageTitle: title );
  

  render() 
    const  pageTitle  = this.state.pageTitle;

    return (
      <TitleContext.Provider value=setTitle: this._setTitle
        <div>
          <Header title=pageTitle />
          this.props.children
          <Footer />
        </div>
     </TitleContext.Provider>
    );
  


class TitleSetter extends React.Component 
    static propTypes = 
        title: PropTypes.string.isRequired
    
    componentDidMount() 
        this.context.setTitle(this.props.title)
    


TitleSetter.contextTypes = TitleContext;

现在在任何组件中,您都可以像这样简单地渲染 TitleSetter

export class Profile extends Component 
  render() 
    return (
        <div>
              <TitleSetter title="Profile" />
              /* other context */
        </div>
    )
  

另外,在查看上下文时,请查看how to access context outside of render上的这个问题

【讨论】:

以上是关于使用道具传递 _setTitle 方法是不是可行?的主要内容,如果未能解决你的问题,请参考以下文章

将对象道具作为 JSX 属性而不是对象传递

将对象作为道具传递是不是会干扰 componentWillReceiveProps?

在 React 路由器 5 中使用变量(不是静态组件)将道具传递给组件

VS 代码中是不是有打开父组件 AKA 传递道具的组件的功能?

Vue - 将方法作为道具传递给孩子

如何使用 onClick 方法通过 react-router 传递道具