나는 많은 react
코드를 읽었 으며 이해하지 못하는 다음과 같은 것을 본다.
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
나는 많은 react
코드를 읽었 으며 이해하지 못하는 다음과 같은 것을 본다.
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
답변:
그게 카레 기능입니다
먼저이 기능을 두 가지 매개 변수로 검사하십시오.
const add = (x, y) => x + y
add(2, 3) //=> 5
여기 다시 카레 양식이 있습니다 ...
const add = x => y => x + y
화살표 기능이없는 동일한 1 개의 코드 는 다음과 같습니다 .
const add = function (x) {
return function (y) {
return x + y
}
}
에 집중 return
다른 방법으로 시각화하는 것이 도움이 될 수 있습니다. 화살표 함수는 다음과 같이 작동한다는 것을 알고 있습니다. 반환 값에 특히주의합시다 .
const f = someParam => returnValue
우리 그래서 add
함수가 반환하는 기능을 - 우리는 추가 명확성을 위해 괄호를 사용할 수 있습니다. 굵은 텍스트는 우리의 함수의 반환 값add
const add = x => (y => x + y)
다시 말하면 add
어떤 숫자의 함수는 함수를 반환합니다.
add(2) // returns (y => 2 + y)
카레 함수 호출
카레 함수를 사용하려면 약간 다르게 호출해야합니다.
add(2)(3) // returns 5
이는 첫 번째 (외부) 함수 호출이 두 번째 (내부) 함수를 반환하기 때문입니다. 두 번째 함수를 호출 한 후에 만 실제로 결과를 얻습니다. 통화를 두 줄로 분리하면 더욱 분명합니다.
const add2 = add(2) // returns function(y) { return 2 + y }
add2(3) // returns 5
코드에 대한 새로운 이해의 적용
이제 작동 방식을 이해 했으므로 코드를 살펴 보겠습니다.
handleChange = field => e => {
e.preventDefault()
/// Do something here
}
우리는 화살표 기능을 사용하지 않고 그것을 표현함으로써 시작할 것입니다…
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
};
};
그러나 화살표 기능은 어휘 적으로 결합하기 때문에 this
, 그것은 것입니다 실제로 더 같이 ...
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
}.bind(this)
}.bind(this)
어쩌면 이제 우리는 이것이 더 명확하게 작동하는 것을 볼 수 있습니다. handleChange
함수 지정하기위한 함수를 생성한다 field
. 이는 애플리케이션 상태를 업데이트하기 위해 각 입력에 자체 리스너를 설정해야하므로 편리한 React 기술입니다. 이 handleChange
함수 를 사용하면 change
각 필드에 대한 리스너를 설정하는 모든 중복 코드를 제거 할 수 있습니다 . 멋있는!
1this
원래 add
함수는 컨텍스트를 사용하지 않기 때문에 어휘 바인딩을 할 필요가 없었으므로이 경우에는이를 유지하는 것이 중요하지 않습니다.
더 많은 화살표
필요한 경우 둘 이상의 화살표 기능을 시퀀싱 할 수 있습니다.
const three = a => b => c =>
a + b + c
const four = a => b => c => d =>
a + b + c + d
three (1) (2) (3) // 6
four (1) (2) (3) (4) // 10
카레 기능은 놀라운 일을 할 수 있습니다. 아래에서 우리 $
는 두 개의 매개 변수를 가진 커리 함수로 정의되었지만 콜 사이트에서는 여러 개의 인수를 제공 할 수있는 것처럼 보입니다. 커링은의 추상화 인수에 대응 -
const $ = x => k =>
$ (k (x))
const add = x => y =>
x + y
const mult = x => y =>
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
부분 적용
부분 적용은 관련 개념입니다. 커리 형태로 정의 할 필요가 없다는 점을 제외하고는 커리와 유사한 함수를 부분적으로 적용 할 수 있습니다.
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const add3 = (x, y, z) =>
x + y + z
partial (add3) (1, 2, 3) // 6
partial (add3, 1) (2, 3) // 6
partial (add3, 1, 2) (3) // 6
partial (add3, 1, 2, 3) () // 6
partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3
partial
자신의 브라우저에서 사용할 수 있는 실습 데모는 다음과 같습니다.
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const preventDefault = (f, event) =>
( event .preventDefault ()
, f (event)
)
const logKeypress = event =>
console .log (event.which)
document
.querySelector ('input[name=foo]')
.addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
$
는 개념을 시연하는 데 사용되었지만 원하는 이름을 지정할 수 있습니다. 공교롭게도하지만 전혀 관계가 $
있다 jQuery를, 같은 인기있는 라이브러리에 사용 된 $
일종의 기능의 전체 라이브러리에 글로벌 엔트리 포인트이다. 나는 그것이 다른 사람들에게도 사용되었다고 생각합니다. _
밑줄이나 lodash와 같은 라이브러리에서 대중화되는 또 다른 것이 있습니다 . 어떤 심볼도 다른 심볼보다 더 의미가 없습니다. 당신 의 의미를 지정 하여 프로그램. 그것은 단지 유효한 JavaScript입니다 : D
$
사용 방법을 살펴보면 더 잘 이해할 수 있습니다 . 구현 자체에 대해 묻는다면 $
값을 받고 x
새로운 함수를 반환하는 함수 k => ...
입니다. 반환 된 함수의 본문을 살펴보면 함수 여야 함 k (x)
을 알 k
수 있습니다. 결과가 무엇이든 k (x)
다시 $ (...)
반환 k => ...
됩니다. 붙어, 알려주세요.
abc(1,2,3)
보다 이상적이지 않습니다 abc(1)(2)(3)
. 코드의 논리에 대해 추론하기가 어렵고 함수 abc를 읽기가 어렵고 함수 호출을 읽기가 더 어렵습니다. abc가하는 일만 알기 전에, abc가 반환하는 명명되지 않은 함수가 무엇인지, 그리고 두 번은 확실하지 않습니다.
화살표 함수 의 사용 가능한 구문을 이해하면 제공 한 예제에서와 같이 '연쇄 화'했을 때 어떤 동작이 도입되는지 이해할 수 있습니다.
여러 매개 변수가 있거나없는 블록 중괄호없이 화살표 함수를 작성하면 함수 본문을 구성하는식이 암시 적으로 반환됩니다. 귀하의 예에서, 그 표현은 또 다른 화살표 기능입니다.
No arrow funcs Implicitly return `e=>{…}` Explicitly return `e=>{…}`
---------------------------------------------------------------------------------
function (field) { | field => e => { | field => {
return function (e) { | | return e => {
e.preventDefault() | e.preventDefault() | e.preventDefault()
} | | }
} | } | }
화살표 구문을 사용하여 익명 함수를 작성하는 또 다른 이점은 해당 함수가 정의 된 범위에 사 전적으로 바인딩된다는 것입니다. 에서 MDN에 '화살표 기능' :
화살표 함수 표현식 에 비해 짧은 구문 함수식 및 사 전적으로 결합 이 값. 화살표 기능은 항상 익명 입니다.
이것은 귀하의 예에서 특히 적합합니다. reactjs신청. 로 @naomik가 가리키는 아웃로, 당신이 종종 액세스 반작용 구성 요소의 멤버 함수를 사용하여 this
. 예를 들면 다음과 같습니다.
Unbound Explicitly bound Implicitly bound
------------------------------------------------------------------------------
function (field) { | function (field) { | field => e => {
return function (e) { | return function (e) { |
this.setState(...) | this.setState(...) | this.setState(...)
} | }.bind(this) |
} | }.bind(this) | }
이것을 화살표로 볼 때마다로 바꾸십시오 function
. function parameters
화살표 앞에 정의됩니다.
따라서 귀하의 예에서 :
field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}
그리고 함께 :
function (field) {
return function (e) {
e.preventDefault();
};
}
문서에서 :
// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression
this
.
간단하고 간단한 🎈
짧은 방법으로 작성된 다른 함수를 반환하는 함수입니다.
const handleChange = field => e => {
e.preventDefault()
// Do something here
}
// is equal to
function handleChange(field) {
return function(e) {
e.preventDefault()
// Do something here
}
}
사람들이하는 이유 ❓
사용자 정의 할 수있는 기능을 작성해야 할 때 직면 했습니까? 또는 고정 매개 변수 (인수)가있는 콜백 함수를 작성해야하지만 더 많은 변수를 함수에 전달해야하지만 전역 변수는 피해야합니까? 당신의 대답이 " 예 "라면 그것을하는 방법입니다.
예를 들어 button
onClick 콜백이 있습니다. 그리고 id
함수 에 전달해야 하지만 onClick
하나의 매개 변수 만 허용 event
하므로 다음과 같은 추가 매개 변수를 전달할 수 없습니다.
const handleClick = (event, id) {
event.preventDefault()
// Dispatch some delete action by passing record id
}
이거 작동 안 할거야!
따라서 전역 변수가 악의적이므로 전역 변수가없는 자체 변수 범위로 다른 함수를 반환하는 함수를 만듭니다.
아래에서 함수 handleClick(props.id)}
가 호출되고 함수를 반환 id
하며 범위 내에 있습니다! 몇 번 눌려도 ID는 서로 영향을 주거나 변경되지 않으며 완전히 격리됩니다.
const handleClick = id => event {
event.preventDefault()
// Dispatch some delete action by passing record id
}
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props.id)}>
Delete
</button>
</div
)
귀하의 질문에있는 예 는 첫 번째 인수를 curried function
사용 arrow function
하고 implicit return
for 를 갖는 예 입니다.
Arrow 함수는이 함수를 사 전적으로 바인딩합니다. 즉, 자체 this
인수가 없지만 포함 this
범위에서 값을 가져옵니다.
위의 코드와 동등한 것은
const handleChange = (field) {
return function(e) {
e.preventDefault();
/// Do something here
}.bind(this);
}.bind(this);
예제에서 주목할 점은 handleChange
const 또는 함수로 정의 하는 것입니다. 아마 당신은 클래스 메소드의 일부로 사용하고 있으며class fields syntax
외부 함수를 직접 바인딩하는 대신 클래스 생성자에서 외부 함수를 바인딩합니다.
class Something{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(field) {
return function(e) {
e.preventDefault();
// do something
}
}
}
예제에서 주목해야 할 또 다른 사항은 암시 적 반환과 명시 적 반환의 차이입니다.
const abc = (field) => field * 2;
위는 암시 적 반환의 예입니다. 값 필드를 인수로 사용하고 반환 field*2
할 함수를 명시 적으로 지정하는 결과 를 반환합니다.
명시적인 반환의 경우 값을 반환하도록 메서드에 명시 적으로 지시합니다.
const abc = () => { return field*2; }
화살표 함수에 대해 주목해야 할 또 다른 사항은 자체 기능이 arguments
없지만 부모 범위에서도 상속한다는 것입니다.
예를 들어 다음과 같은 화살표 기능을 정의하면
const handleChange = () => {
console.log(arguments) // would give an error on running since arguments in undefined
}
대체 화살표 기능으로 사용할 수있는 나머지 매개 변수를 제공합니다.
const handleChange = (...args) => {
console.log(args);
}
그것은 완전히 관련이 없지만 언급 된 질문에 react uses case (그리고 나는이 SO 스레드에 계속 부딪칩니다) : 이중 화살표 기능의 중요한 측면이 여기에 명시 적으로 언급되어 있지 않습니다. '첫 번째'화살표 (함수) 만 이름이 지정되고 (따라서 런타임에 따라 '구별 가능'), 다음 화살표는 익명이며 React 관점에서 모든 렌더링에서 '새로운'객체로 계산됩니다.
따라서 이중 화살표 기능을 사용하면 모든 PureComponent가 항상 다시 렌더링됩니다.
예
다음과 같이 변경 핸들러가있는 상위 구성 요소가 있습니다.
handleChange = task => event => { ... operations which uses both task and event... };
그리고 다음과 같은 렌더링으로 :
{
tasks.map(task => <MyTask handleChange={this.handleChange(task)}/>
}
handleChange는 입력 또는 클릭에 사용됩니다. 그리고 이것은 모두 작동하며 매우 멋지게 보입니다. 그러나 그것은 완전히 관련되지 않은 상태 변경과 같이 부모가 다시 렌더링하게 만드는 모든 변경 사항은 PureComponents 임에도 불구하고 모든 MyTask를 다시 렌더링한다는 것을 의미합니다.
이것은 '가장 바깥 쪽'화살표를 전달하거나 사용자 정의 shouldUpdate 함수를 작성하거나 사용자 정의 shouldUpdate 함수를 작성하거나 명명 된 함수 작성 (및 수동으로 바인딩)과 같은 기본으로 돌아가는 등 여러 가지 방법으로 완화 될 수 있습니다.