在React组件中使用函数属性的正确方法

时间:2018-02-03 21:33:51

标签: reactjs

我是React的新手,从我已经完成的有限教程等我已经看到应用程序状态处于可能与呈现它的组件不同的级别,因为组件能够编辑一个函数作为属性传入并以这种方式使用的状态。这一切都很好但是将函数传递给嵌套组件在什么时候是荒谬的呢?例如,我有

<App>
  <Container>
    <Item>
      <ItemChangeMenu/>
    </Item>
  </Container>
</App>
如果AppchangeItemContainer都具有Item属性,则

ItemChangeMenu具有状态和函数onItemChanged传递它?

1 个答案:

答案 0 :(得分:2)

props传递给孩子有两种主要方法:

  1. 明确 - 在每个级别上将道具作为个人传递:

    &#13;
    &#13;
        const Container = (props) => (
          <Item
            onItemChange={props.onItemChange}
            value={props.value} />
        );
    
        const Item = (props) => (
          <ItemChangeMenu
            onItemChange={props.onItemChange}
            value={props.value} />
        );
    
        const ItemChangeMenu = (props) => (
          <input
            onChange={props.onItemChange}
            value={props.value} />
        );
    
        class App extends React.Component {
          state = { value: 'Hello World...' }
          onItemChange = ({ target }) => {
            this.setState(state => ({ value: target.value }))
          }
          render() {
            const { value } = this.state;
            return (
              <Container
                onItemChange={this.onItemChange}
                value={value} />
            );
          }
        }
    
        ReactDOM.render(<App />, document.getElementById('root'));
    &#13;
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
        <div id="root"></div>
    &#13;
    &#13;
    &#13;

  2. 隐式 - 传递整个props对象但传播它(新的 ES2018 feature):

    &#13;
    &#13;
        const Container = (props) => <Item {...props} />;
    
        const Item = (props) => <ItemChangeMenu {...props} />;
    
        const ItemChangeMenu = (props) => (
          <input
            onChange={props.onItemChange}
            value={props.value} />
        );
    
        class App extends React.Component {
          state = { value: 'Hello World...' }
          onItemChange = ({ target }) => {
            this.setState(state => ({ value: target.value }))
          }
          render() {
            const { value } = this.state;
            return (
              <Container
                onItemChange={this.onItemChange}
                value={value} />
            );
          }
        }
    
        ReactDOM.render(<App />, document.getElementById('root'));
    &#13;
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
        <div id="root"></div>
    &#13;
    &#13;
    &#13;

  3. 当然,每种模式都有利弊。

    使用显式模式,您可以清楚地看到传递了哪些道具,并且您可以手动决定要传递的道具。

    这种方法的主要注意事项是,这很乏味且很难重构。

    使用隐式模式,您只需传递一个对象而忘记它,您需要传递一个新的道具?它已经下了烟囱。如果您需要重构,更改道具名称或重新排序组件层次结构,则无需更改道具名称。

    然而,这种方法的主要警告是,你可能会传递更多的道具然后你需要。这可能导致不必要的componentWillReceiveProps号召 当然,您可以使用destructure来最小化它:

    const {someProp, someOtherProp, ...rest} = this.props;
    // ...  
    <Child {...rest} />
    

    但这与采用明确的方法几乎相同。

    有第3个选项虽然它与props API无关。
    它叫context。使用上下文API,您可以跳过&#34;跳过&#34;水平并直接从祖父母那里抓住objects

    听起来不错,但如果你看一下DOCS

      

    为什么不使用上下文

         

    绝大多数应用程序不需要   使用上下文。

         

    如果您希望应用程序稳定,请不要使用上下文。它是一个   实验API,它很可能在未来的版本中破坏   反应。

    正如文档中所述,这是一个&#34;实验性API,它可能会破坏&#34; ,那一天已经到来,a new context API就在它上面了#39 ;方式和方式可能会改变我们使用props的方式或一起做出反应。

    context功能不是没有人使用的功能,react-reduxreact-routerreact-mobx等重要库正在使用并依赖于它。