0

So I've always thought of arrow functions to be a new better and version of normal js functions until today. I was following a tutorial on how to use firestore to store data when I came across a problem that made realise the two are different and work in a weird way. His code looked like this:

//component
function Todos() {
    const [ todo, setTodo ] = useState('');
    const ref = firestore().collection('todos');
    // ...
    async function addTodo() {
        await ref.add({ title: todo, complete: false});
        setTodo('');
    }
    // ...
}

My code looked like this:

//component

const Todos = () => {
    const ref = firestore().collection('todos');
    const [todo, setTodo] = useState('');

    const addTodo = async () => {
        const res = await ref.add({ title: todos, complete: false   });
        setTodo('');
    };
};

Now his version worked, while mine didn't. After changing my code to look like his, it worked. But the weird thing i realised was this: after clicking on the button that invoked that function for the first time (with his function), i changed the code back to mine and it worked the second time. I did some reading on the two functions but i couldn't get to reasoning behind why this happened.

Community
  • 1
  • 1
abdi
  • 519
  • 1
  • 5
  • 16
  • 1
    Looks good to me, I don't see any overt errors. Is there an actual question in there somewhere? If I had to guess, your first version may have had an error that you somehow fixed or corrected in your second version. Or something wasn't saved fully in your editor. – Drew Reese Mar 15 '20 at 04:42
  • 1
    Does this answer your question? [Correct use of arrow functions in React](https://stackoverflow.com/questions/48699573/correct-use-of-arrow-functions-in-react) – Randy Casburn Mar 15 '20 at 04:50
  • Kindly check the summary `function-binding-in-details`: https://github.com/ibarapascal/access-catalog/blob/master/blog/summary-of-react-develop-practice/summary-react.md/#function-binding-in-details – keikai Mar 15 '20 at 05:06
  • Is there anything in `addTodo` or in `Todos` which references `this`? – CertainPerformance Mar 15 '20 at 05:17
  • @DrewReese No my first version had no errors in it. I tried this multiple times and the result was the same (it didn't work the first time with my code and worked after clicking the button once and changingit after. My question is why does it not work the first time and only work the second time? – abdi Mar 15 '20 at 05:52
  • @CertainPerformance no – abdi Mar 15 '20 at 05:52
  • So you try with your code, and it doesn't work. So you change it all to be like the tutorial, save it, reload app, and it works? Then undo those changes, save and reload app, and it still works? – Drew Reese Mar 15 '20 at 05:57
  • @DrewReese yes. Exactly like you said it. Isn't that weird – abdi Mar 15 '20 at 16:26

1 Answers1

0

Arrow functions and normal function are not equivalent.

Here is the difference:

Arrow function do not have their own binding of this, so your this.setState refer to the YourClass.setState.

Using normal function, you need to bind it to the class to obtain Class's this reference. So when you call this.setState actually it refer to YourFunction.setState().

Sample Code

class FancyComponent extends Component {
    handleChange(event) {
        this.setState({ event }) // `this` is instance of handleChange
    }

    handleChange = (event) => {
        this.setState({ event }) // `this` is instance of FancyComponent
    }
}
Asad
  • 563
  • 3
  • 16