【问题标题】:React when to use a Function in Props?React 何时在 Props 中使用函数?
【发布时间】:2020-04-03 16:46:11
【问题描述】:

在反应中, 什么时候在 Props 中使用函数?

例如在下面的代码中,有时你不会在 prop 中使用函数, 但有时你会这样做。

import React, { useState } from 'react';

const IterationSample = () => {
  const input = React.createRef();
  const [names, setNames] = useState(
    [
      { id: 1, text: 'John' },
      { id: 2, text: 'Jake' },
      { id: 3, text: 'JJ' },
      { id: 4, text: 'Jesus' }

    ])
  const [inputText, setInputText] = useState('');
  const [nextId, setNextId] = useState(5);

  const onChange = e => setInputText(e.target.value);
  const onRemove = id => {
    const nextNames = names.filter(name => name.id !== id);
    setNames(nextNames);
  }
  const namesList = names.map(name => <li key={name.id} onDoubleClick={() => onRemove(name.id)}>{name.text}</li>);
  const onClick = () => {
    const nextNames = names.concat({
      id: nextId,
      text: inputText
    });
    setNextId(nextId + 1);
    setNames(nextNames);
    setInputText('');
    input.current.focus();
  }

  const onEnter = (e) => {
    if (e.key === 'Enter') {
      onClick();
    }
  }


  return (
    <>
      <input ref={input} value={inputText} onChange={onChange} onKeyPress={onEnter} />
      <button onClick={onClick} >Add</button>
      <ul>{namesList}</ul>
    </>
  );
};


export default IterationSample;

这里你使用 ()=> onDoubleClick={() =&gt; onRemove(name.id) 中的一个函数 但是,onKeyPress={onEnter}onChange={onChange} 中都没有

那么什么时候在 props 中使用函数呢?

【问题讨论】:

  • onDoubleClick={() =&gt; onRemove(name.id) 中,您将自定义变量传递给函数。当您只使用函数名称时,您无法传递自定义变量。只有回调传递的变量才会发送到函数。在您的示例中,回调事件将被发送到 onChange 等等。
  • 看看这个question

标签: javascript reactjs


【解决方案1】:

你的三个例子都使用了一个函数:

onDoubleClick={() => onRemove(name.id)}
onKeyPress={onEnter}
onChange={onChange}

唯一的区别是其中一个需要为函数指定一个参数(onRemove),而另外两个不需要。

如果属性传递的参数(在本例中为 onKeyPressonChange)正是函数所需要的,那么您只需按原样引用函数。但是,如果您需要自定义传递给函数的内容(在本例中为 onRemove),则可以将其包装在一个新函数中以包含该自定义项。

【讨论】:

    【解决方案2】:

    您基本上在需要传递额外参数时使用它(event selft 除外)。 前任。当您想在您的情况下通过id 时:

    onClick={(e) => onRemove(name.id)}
    //or together with the event
    onClick={(e) => onRemove(e, name.id)}
    

    否则当你不需要在函数内部传递参数,或者你只需​​要传递event时你可以这样写:

    onClick={onRemove}
    

    【讨论】:

      【解决方案3】:

      这个

      onClick={onClick}
      

      等价于

      onClick={(e) => onClick(e)}
      

      对于第一种情况,您将函数本身作为道具传递。

      对于第二种情况,您定义了一个内联函数,它使用参数(e) 调用onClick 函数。

      通常您可以将函数本身作为道具传递,除非您想在调用函数时添加其他参数。例如,

      onClick={(e) => onClick(e, name.id)}
      

      【讨论】:

        【解决方案4】:

        :)

        David 和 Ertan 的回答非常好而且完整。 我再补充两点。

        首先,考虑到 reactjs 的良好实践和性能,不要在渲染中使用箭头函数。

        根据eslint规则eslint rules

        A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is bad for performance, as it may cause unnecessary re-renders if a brand new function is passed as a prop to a component that uses reference equality check on the prop to determine if it should update.

        其次,如果您需要自定义传递给函数的内容(在本例中为 on Remove),您可以使用 lodash 的替代方法:partial

        official doc

        这里是您的代码示例:

        const namesList = names.map(name =>
                     <li key={name.id}
                         onDoubleClick={ _.partial(this.onRemove, name.id)}
                     >
                         {name.text}
                     </li>
                   );

        祝你有美好的一天

        【讨论】:

        • 嘿,感谢您提供非常详细的帖子!你能把“这个”去掉吗?从 this.onRemove 开始,代码就可以工作了。
        • 如果它在一个类中没有:) 但在这种情况下是的对不起我的坏:angel:
        【解决方案5】:

        澄清一下,因为您似乎没有得到您正在寻找的适合初学者的答案:

        诸如“onKeyPress”或“onChange”之类的东西带有一个隐式事件。那是什么意思?这意味着无论你绑定到那个组件的任何函数,它都会被一个“事件”触发,这将是你输入的任何函数的参数。事实上,如果你查看函数本身,你会注意到他们接受一个论点,“e”代表事件。因此,如果有帮助,您可以将其中一些命令视为说

        onKeyPress={()=>onEnter(keyPressEvent)}

        事件中会包含一些有用的数据,但通常我们唯一关心的是用户按下了哪个键,或者(如果发生更改)输入的新内容是什么.

        对于像 onDoubleClick 这样的东西,你给它一些额外的数据。您可以使用 javascript 进行一些花哨的操作来识别双击的内容及其属性,但这很麻烦,添加了不必要的代码,并且往往会混淆您正在编码的任何意图。因此,最终只提供您想要的任何功能会更容易。

        【讨论】:

          猜你喜欢
          • 2016-09-06
          • 2021-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-16
          • 1970-01-01
          • 2018-05-06
          • 1970-01-01
          相关资源
          最近更新 更多