如何在React组件内自定义请求

时间:2018-01-24 13:47:53

标签: javascript reactjs react-component

我有一个组件ContentHeader,我将在几乎每个内容中使用它,它提供带标题的标题和两个按钮,New和Search。

import React from 'react';
import Title from 'components/Title';
import BtnSearch from 'components/BtnSearch';
import BtnNew from 'components/BtnNew';

class ContentHeader extends React.Component {
  constructor (props) {
    super(props);
  }

  render () {
    return (
      <div className='content-header'>
        <Title name={this.props.title} />

        <ul className='actions'>
          <li className='action-item'>
            <BtnSearch />
          </li>
          <li className='action-item'>
            <BtnNew />
          </li>
        </ul>
      </div>
    );
  }
}

export default ContentHeader;

我在ContentHeader中使用的按钮组件:

// Component Button Search
import React from 'react';
import { NavLink } from 'react-router-dom';

class BtnSearch extends React.Component {
  constructor (props) { 
    super(props);
  }

  render () {
    return (
      <a className='btn-actions btn-search' onClick=CUSTOM_REQUEST>
        <span className="icon-center"></span>
      </a>
    )
  }
}

export default BtnSearch;


// Component Button New
import React from 'react';
import { NavLink } from 'react-router-dom';

class BtnNew extends React.Component {
  constructor (props) { 
    super(props);
  }

  render () {
    return (
      <NavLink to=CUSTOM_REQUEST className='btn-actions btn-new'>
        <span className="icon-center"></span>
      </NavLink>
    )
  }
}

export default BtnNew;

假设我有项目,合同和小工具的主要内容,我需要在里面使用ContentHeader。

对于每个主要内容,我将有一个不同的标题标签,我可以通过道具传递,因为只有一个层次。但是,我对ContentHeader组件中的每个按钮都有不同的请求,与它所属的主要内容有关。

那么,我如何将这些不同的请求传递给与我的主要内容相关的按钮?道具也是?如果我有一个更深层的组件树怎么样?

PS:作为一个例子,我在我的按钮组件中使用了NavLink和一个简单的onClick,标志为CUSTOM_REQUEST

谢谢!

2 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您需要能够根据内容类型将特定请求传递到相应的ContentHeader组件。

您绝对可以通过props将该请求函数传递给该页面/内容组件的子按钮。

import React from 'react';
import Title from 'components/Title';
import BtnSearch from 'components/BtnSearch';
import BtnNew from 'components/BtnNew';

class ContentHeader extends React.Component {
  constructor (props) {
    super(props);
  }

  render () {
    const { myRequestFunc } = this.props
    //...or if not es15
    var myRequestFunc = this.props.myRequestFunc

    return (
      <div className='content-header'>
        <Title name={this.props.title} />

        <ul className='actions'>
          <li className='action-item'>
            <BtnSearch />
          </li>
          <li className='action-item'>
            <BtnNew requestFunc={myRequestFunc} />
          </li>
        </ul>
      </div>
    );
  }
}

export default ContentHeader;

无论如何,这是简单的方法。您可以 - 根据应用程序的大小 - 探索Redux,React-Redux和Redux-Thunk或Redux-Saga,以避免不可避免地将道具传递到几个级别。 Checkout using redux with react

答案 1 :(得分:1)

如果你使用简单的反应并且嵌套太大,那么将道具传递到每个级别将变得非常困难。在这种情况下,您可以使用context API来做出反应。

  

您可以在此处阅读:how-to-use-context

但不鼓励使用上下文。

  

您可以在此处阅读:why not to use context

您可以尝试以下方法

function Wrapper(newBtnAction, searchBtnAction, label, props) {
  return ( < ContentHeader {...props
    }
    label = {
      label
    }
    newBtnAction = {
      newBtnAction
    }
    searchBtnAction = {
      searchBtnAction
    }
    />
  )
}

现在您可以在任何地方使用包装组件,只需要通过store.dispatch传递正确的函数绑定

假设您有一个组件B,C,D,E,您可以像这样使用它

class B extends React.Component {

  render() {
    // get proper actions here
    const {
      newBtnAction,
      searchBtnAction,
      label
    } = this.props
    return ( < C >
      < D >
      < E > {
        Wrapper(newBtnAction, searchBtnAction, label, this.props)
      } < /E> < /D> < /C>
    )
  }
}
  

我们将此概念称为反应中的高阶组件。这是   基本上是反应组件方法的设计模式

注意:提示括号,不执行代码