简体   繁体   English

Reactjs setState箭头函数语法

[英]Reactjs setState arrow function syntax

As per the React Docs we can have two ways for setState one with object syntax and other with function which they have shown as below 根据React Docs,我们可以通过两种方式使用对象语法的setState和其他具有如下所示的函数的方法

this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

My understanding of arrow function syntax is like () => {} where flower brackets are followed after arrow => , but as per the sample it is round braces instead of flower brackets 我对箭头函数语法的理解类似于() => {} ,其中在箭头=>之后遵循花括号,但根据示例,它是圆括号而不是花括号

What is the difference between these syntax ()=>{} and ()=>({}) . 这些语法()=>{}()=>({})之间有什么区别。

Sample Code tried as per the docs which is working when this.setStage(prevStage=>({})) syntax is used in handleClick function, and if you change it to this.setState(prevStage=>{}) it wont toggle the button value. handleClick函数中使用this.setStage(prevStage=>({}))语法时,根据文档尝试示例代码,如果将其更改为this.setState(prevStage=>{})则不会切换按钮值。

Below is the working code: 以下是工作代码:

class Toggle extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isToggleOn : true
        }
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(prevState => ({
            isToggleOn: !prevState.isToggleOn
          }));
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>
                    {this.state.isToggleOn ? 'ON' : "OFF"}
                </button>
            </div>
        );
    }
}

Later I referred MDN and found details under Advanced Syntax section, that if you want to return objects implicitly then we need to enclose it within () , that answered my question. 后来我引用了MDN并在高级语法部分下找到了详细信息,如果你想隐式返回对象,那么我们需要将它包含在()中,这回答了我的问题。

// Parenthesize the body of function to return an object literal expression: //括号化函数体以返回对象文字表达式:

params => ({foo: bar}) params =>({foo:bar})

There are 2 main issues to consider here: 这里有两个主要问题需要考虑:

  1. How arrow functions works? 箭头功能如何工作?

  2. What setState expects when passing function as a parameter? function作为参数传递时, setState需要什么?

Answers: 回答:

  1. Arrow functions can return a value implicitly or explicitly. 箭头函数可以隐式或显式返回值。
    When there is no function body (no curly brace {} ) then you are returning implicitly: 当没有函数体(没有大括号{} )时,你会隐式返回:

     const x = () => 'we are returning a string here'; 

    When we use a function body, we need to use the return key word: 当我们使用函数体时,我们需要使用return关键字:

     const x = () => { return 'another string returned' }; 

    There is another option to return something without the return key word, you can wrap the curly brace with parentheses () and this will signal the engine that the curly brace are not a function body but an object, this is considered as creating an expression: 还有另一个选项可以在没有return关键字的情况下返回一些东西,你可以用括号()包裹大括号,这将向引擎发出大括号不是函数体而是一个对象的信号,这被认为是创建一个表达式:

     const x = () => ({myKey: 'some string'}); 

    This is similar as we usually do with function expressions. 这与我们通常使用函数表达式类似。
    Especially with IIFE ( I mmediately I nvoked F unction E xpression) : 特别是随着IIFE( mmediately nvoked˚FË上的表达):

     (function() { //some logic... })(); 

    If we will not return anything, then the function will just return undefined . 如果我们不返回任何内容,那么该函数将返回undefined

  2. As for setState , when you pass a function as a parameter, it expect that this function will return an object. 对于setState ,当您将函数作为参数传递时,它期望此函数将返回一个对象。
    When your function didn't return anything (as stated above) it actually returned undefined . 当你的函数没有返回任何东西时(如上所述)它实际上返回undefined
    JavaScript won't yield an error as this is not an error. JavaScript不会产生错误,因为这不是错误。 its just a function that returns nothing ( undefined ). 它只是一个不返回任何东西的函数( undefined )。

Here is a running example of your code without the wrapping parentheses: 以下是没有包装括号的代码的运行示例:

 class Toggle extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true } this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => { return { // we must return an object for setState isToggleOn: !prevState.isToggleOn } }); } render() { return ( <div> <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : "OFF"} </button> </div> ); } } ReactDOM.render(<Toggle />, document.getElementById('root')); 
 <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> 

Edit 编辑
As a followup to your comments 作为您的意见的后续

I would expect Javascript to throw error when we return just key : value without enclosing parenthesis, ie, () => {key:value} - which means it is trying to return 'key:value' and not Object, and this should be an JS error, but it did not throw any error. 当我们只返回key:value而不包含括号时,我希望Javascript会抛出错误,即()=> {key:value} - 这意味着它试图返回'key:value'而不是Object,这应该是一个JS错误,但它没有抛出任何错误。 Please correct me if my understanding is wrong 如果我的理解是错误的,请纠正我

It is not returning a key value, it is a "void" function that returns undefined . 它没有返回键值,它是一个返回undefined的“void”函数。
See this running snippet: 看到这个正在运行的代码段:

 const x = () => {myKey: 'myValue'}; const y = x(); console.log(y); 

Edit#2 编辑#2
Followup to your other comments (which is basically kind of a whole different question in my opinion). 跟进你的其他评论(在我看来,这基本上是一个完全不同的问题)。

let y = function() {'abc':1} - syntax error, let y = function(){abc:1} and let y = function(){ return {'abc':1} } - no error, where first one (syntax error) we are trying to assign 1 to string abc, which is same as 3rd sample (no error), and 2nd example assigning 1 to abc - works when there is no quotes. 让y = function(){'abc':1} - 语法错误,让y = function(){abc:1}并让y = function(){return {'abc':1}} - 没有错误,其中第一个(语法错误)我们试图将1分配给字符串abc,这与第3个样本(无错误)相同,第2个例子将1分配给abc - 在没有引号时起作用。 Please explain the difference of these 3 samples and why 1st one fails and not 2nd example 请解释这三个样本的区别以及为什么第一个失败而不是第二个例子

OK, this is getting interesting. 好的,这很有意思。

where first one (syntax error) we are trying to assign 1 to string abc... 我们试图将第一个(语法错误)分配给字符串abc ...

No we are not. 不,我们不是。
We are trying to create a label: , but labels can't be strings! 我们正在尝试创建一个label:但标签不能是字符串!
Same as variables can't be strings - var 'x' = 1 . 与变量相同不能是字符串 - var 'x' = 1

This is a valid syntax in JavaScript: 这是JavaScript中的有效语法:

const y = function(){b:2};

What we are doing here is creating a label: named a and this label has an expression of 1 (we are not doing anything with this label.). 我们在这里做的是创建一个label:命名为a ,此标签的表达式为1 (我们没有对此标签做任何事情。)。

 const x = () => {a:1}; const y = function(){a:1}; 

This syntax is invalid: 此语法无效:

const y = function() { 'a': 1 };

This is not valid because labels can't start with a string: 这是无效的,因为标签不能以字符串开头:

 const x = () => { 'a': 1 }; const y = function() { 'a': 1 }; 

And again, this is not a key:value pair, the curly brace are the function's BODY . 而且,这不是key:value对,大括号是函数的BODY

If you only write () => {} this explicitally means that the function does more than just return something. 如果你只写()=> {}这明确意味着该函数不仅仅返回一些东西。

For example: 例如:

const logAndReturn = (val) => {
  console.log(val)
  return val
}

But let's say you have a function that takes params and returns an object based on those params. 但是,假设您有一个函数,它接受参数并返回基于这些参数的对象。

const createUser = (x) => { 
  prop: x
}

This will prompt an error, cause this basically translates to: 这将提示错误,因为这基本上转换为:

function createUser(x) { 
  prop:x 
}

With paranthesis you are still using the default return from the arrow function. 使用paranthesis,您仍然使用箭头函数的默认返回值。

const createUser = (name, email) => ({})
function createUser(name, email) { return {} )

the simple answer is 简单的答案是

()=>({})

also it's equal to 它也等于

()=> {
   return {}
 }

return an empty object,here parentheses around {} mean return . 返回一个空对象,这里的括号{}表示return also you know we must pass object to setState so we insert any thing we want to state between {} 你也知道我们必须将对象传递给setState所以我们要在{}之间插入任何想要说明的东西

()=>({any thing you want to set to state})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM