skip to Main Content

I’m using functional components.

<Column customFunc={myFunc} />

How should myFunc be defined?

function myFunc(e) { // code }

or

const myFunc = (e) => { // code }

Only when defining it using function keyword aka function declaration, I get this error from ESLint: JSX props should not use functions eslint (react/jsx-no-bind)

It looks like function expressions are not regarded as functions by ESLint and that’s why it doesn’t show that warning when they’re used. Aside from hoisting and immutability, how should I define my functions inside a functional component? Does it have any impact on the way components render?


Also, if myFunc (which is defined inside another component) returns a JSX, is that considered bad?

function myFunc(props) { <CustomJSX {... props} controlParentState={editParentState} /> }

I get ESLint error/warning saying: Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “App” and pass data as props. eslint (react/no-unstable-nested-components)

My problem is, if I define myFunc outside of parent component, how can I pass props to it when I call it (and would props have controlParentState in this case and would it be able to alter parent state)?

2

Answers


  1. Problem 1:

    So, if I understand your problem correctly, you want to create a function that can accept props wherever it’s defined.

    This is a very simple misconception. Components can be functions in react.

    Just define myFunc like this.

    function MyFunc ({props}) {
    // Logic goes here
    return(
        <>
        {/* Your JSX */}
        </>
    )
    

    }

    You don’t have to pass MyFunc as a prop, just use it like a normal component. For your case, use it in the Column component like this.

    <Column> <MyFunc props={props}/> </Column>
    

    Problem 2:

    Directly altering or changing the parent state from the child component defies the whole concept of React. See here

    Therefore, keep MyFunc pure by making it it’s own component (function) that can accept props. That’s also what ESlint is saying.

    Instead, move this component definition out of the parent component “App” and pass data as props.
    

    React docs is an excellent site for further references.

    Login or Signup to reply.
  2. About JSX props should not use functions eslint (react/jsx-no-bind):

    The core problem ESLint is trying to notify you is that it’s inefficient to declare a function in a component, because it gets redeclared on each re-render due to strict checking.

    To solve such problem, you can either move the function declaration/expression out of the component, or you might optimize if necessary using a useCallback hook to memoize the function:

    function YourComponent() {
       const memoizedOnClick = useCallback(() => console.log(1), []);
    
       return <button onClick={memoizedOnClick}>blah</button>;
    }
    

    In that case, the function will be memoized and will hence reduce the re-renders, although I personally prefere to avoid using useCallback unless necessary. I personally stick with Dan Abramov’s post about memos in general, which applies to this as well.

    So, to summarize how to solve the first problem, either:

    1. Move the function outside of the component.
    2. (edge case if really necessary) use useCallback with the dependencies or none to simply memoize the function.

    In both cases, you will prevent unnecessary rerenders.


    About Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “App” and pass data as props. eslint (react/no-unstable-nested-components):

    There isn’t that much to talk about this: you should avoid passing functions that renders components unless, once again, there is a very good reason to do to so.

    To avoid such scenario, provide instead a Component (which is a function anyway) that accepts some props, and inject such props, declared outside of the rendered component (so, anywhere else literally).

    Once again, this error is still related to prevent unnecessary rerenders because of strict equality checks.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search