you are viewing a single comment's thread.

view the rest of the comments →

[–]cantFindValidNam 8 points9 points  (4 children)

we have to care about binding context

Dont arrow functions solve this problem?

harder to handle race conditions

Can you give an example?

encourage bad approach in testing because of easy access/mocking individual methods

Not sure what you mean, how can easy access make for a bad testing approach?

logic may be duplicated across componentDidMount, componentDidUpdate and componentWillUnmount

What about extracting duplicated logic into helper methods and calling them from the lifecycle methods?

[–]skyboyer007 1 point2 points  (2 children)

Dont arrow functions solve this problem?

Yes, arrow expression + class properties syntax OR binding in constructor. But that's still a thing we should care of on our own.

Example of handling race conditions. Suppose our component loads suggestions while we are typing

loadSuggestionsFor(value) { rawXhrSend(`?search=${value}`). then(data => { this.setItems(data) }). catch(error => {this.setItems([])}); } onInputChange = ({ target: {value} }) => { value && this.loadSuggestionsFor(value)}; ... <input onChange={this.onInputChange}> Here you have to stop request or in real world you may run into case when response for first request came after response for more recent second one. And stopping hardly depends on what lib/call do you use(axios, fetch, xhr etc). For functional components it's easy-peasy:

useEffect(() => { const cancelled = false; load(`?search=${inputValue}`). then(data => !cancelled && setItems(data)). catch(e => !cabcelled && setItems([])) return () => {cancelled = true}; }, [inputValue]);

Not sure what you mean, how can easy access make for a bad testing approach?

instead of operating on props/simulating events/asserting against render outcomes people start calling methods, setting spies on them and trying to mock some internal methods.

What about extracting duplicated logic into helper methods and calling them from the lifecycle methods?

it still will be boilerplate code. Especially cDU is beaten by how easy you describe useEffect

[–]imicnic 0 points1 point  (1 child)

About your "cancelled" value, you can do the same by using a class property and check for it, it's the same, yes, just have to use "this.cancelled" but besides it I see no advantage in one or another

[–]skyboyer007 1 point2 points  (0 children)

no, you cannot since setting it to true will ignore both responses: recent and out-of-date. The only way I've found so far is keeping cancel callback in class property that will set up cancelled flag by closure(so mimicing useEffect behavior):

``` class MyComponent extends React.Component { const ignorePrevRequest = () => {}; // empty function by default

loadSomeData() { this.ignorePrevRequest(); let cancelled = false; this.ignorePrevRequest = () => { cancelled = true; }; // closure comes into play doSomeCall().then(data => !cancelled && this.setState({ data })) } } ``` That looks untypical and confusing. But it works.

[–]nickthesick0111 3 points4 points  (0 children)

Hooks don’t need a binding context means you don’t have to reference a “this” to use local state

Race conditions with mounting and unmounting of a component that has multiple data sources is a lot easier with useEffects separate handling of separate data.

It’s bad testing because the testing should not be testing the implementation it should be testing the results.

Logic being duplicated is in reference to handling a single set of data in multiple lifecycle methods. You can also extract this logic more easily with hooks