Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should functions in function components go?

People also ask

How do you create a function inside a functional component?

We can create a functional component to React by writing a JavaScript function. These functions may or may not receive data as parameters. In the functional Components, the return value is the JSX code to render to the DOM tree. Example: Program to demonstrate the creation of functional components.

How do you write a function inside a functional component in React?

Have you wondered how to create a component in React? To answer, it is as simple as creating a function returning an HTML-like syntax. import React from 'react'; function Counter({n}) { return ( <div>{n}</div> ); } export default Counter; Now let's see what happened in the code above.

Can a function be a component?

A function that could be used as a component is not necessarily will be used as a component. So, to be a component, it needs to be used as <Text /> instead. Same with CounterWithWeekday . By the way, components can return plain strings.


The first thing to note is that stateless functional components cannot have methods, you shouldn't count on calling update or draw on a rendered Ball if it is a stateless functional component.

In most cases you should declare the functions outside of the component function so you declare them only once and always reuse the same reference. When you declare the function inside, every time the component is rendered the function will be defined again.

There are cases in which you will need to define a function inside the component to, for example, assign it as an event handler that behaves differently based on the properties of the component. But still you could define the function outside Ball and bind it with the properties, making the code much cleaner and making the update or draw functions reusable.

// You can use update somewhere else
const update (propX, a, b) => { ... };

const Ball = props => (
  <Something onClick={update.bind(null, props.x)} />
);

If you're using hooks, you can use useCallback to ensure the function is only redefined when one of its dependencies (props.x in this case) changes:

const Ball = props => {
  const onClick = useCallback((a, b) => {
    // do something with a, b and props.x
  }, [props.x]);

  return (
    <Something onClick={onClick} />
  );
}

This is the wrong way:

const Ball = props => {
  function update(a, b) {
    // props.x is visible here
  }

  return (
    <Something onClick={update} />
  );
}

When using useCallback, defining the update function in the useCallback hook itself our outside the component becomes a design decision more than anything, you should take into account if you're going to reuse update and/or if you need to access the scope of the component's closure to, for example, read/write to the state. Personally I choose to define it inside the component by default and make it reusable only if the need arises, to prevent over-engineering from the start. On top of that reusing application logic is better done with more specific hooks, leaving components for presentational purposes. Defining the function outside the component while using hooks really depends on the grade of decoupling from React you want for your application logic.


You can place functions inside stateless functional components:

function Action() {
    function handlePick(){
        alert("test");
    }

    return (
        <div>
            <input type="button" onClick={handlePick} value="What you want to do ?" />
        </div>
    )
}

But it's not a good practice as the function handlePick() will be defined every time the component is rendered.

It would be better to define the function outside the component:

function handlePick(){
    alert("test");
}

function Action() {
    return (
        <div>
            <input type="button" onClick={handlePick} value="What you want to do ?" />
        </div>
    )
}

If you want to use props or state of component in function, that should be defined in component with useCallback.

function Component(props){
  const onClick=useCallback(()=>{
     // Do some things with props or state
  },[])

  return <Something {...{onClick}} />
}

On the other hand, if you don't want to use props or state in function, define that outside of component.

const computeSomethings=()=>{
   // Do some things with params or side effects
}

function Component(props){
  return <Something onClick={computeSomethings} />
}

For HTML tags you don't need useCallback because that will handle in react side and will not be assigned to HTML

function Component(props){
  const onClick=()=>{
     // Do some things with props or state
  }

  return <Something {...{onClick}} />
}

Edit: Functions in hooks

For the use function in hooks for example useEffect, my suggestion is defining function inside useEffect, if you're worried about DRY, make your function pure call it in hook and give your params to it. What about hooks deps? You should/could add all of your params to hooks deps, but useEffect just needs deps which should affect for them changes.


We can use the React hook useCallback as below in a functional component:

const home = (props) => {
    const { small, img } = props
    const [currentInd, setCurrentInd] = useState(0);
    const imgArrayLength = img.length - 1;
    useEffect(() => {
        let id = setInterval(() => {
            if (currentInd < imgArrayLength) {
                setCurrentInd(currentInd => currentInd + 1)
            }
            else {
                setCurrentInd(0)
            }
        }, 5000);
        return () => clearInterval(id);
    }, [currentInd]);
    const onLeftClickHandler = useCallback(
        () => {
            if (currentInd === 0) {

            }
            else {
                setCurrentInd(currentInd => currentInd - 1)
            }
        },
        [currentInd],
    );

    const onRightClickHandler = useCallback(
        () => {
            if (currentInd < imgArrayLength) {
                setCurrentInd(currentInd => currentInd + 1)
            }
            else {

            }
        },
        [currentInd],
    );
    return (
        <Wrapper img={img[currentInd]}>
            <LeftSliderArrow className={currentInd > 0 ? "red" : 'no-red'} onClick={onLeftClickHandler}>
                <img src={Icon_dir + "chevron_left_light.png"}></img>
            </LeftSliderArrow>
            <RightSliderArrow className={currentInd < imgArrayLength ? "red" : 'no-red'} onClick={onRightClickHandler}>
                <img src={Icon_dir + "chevron_right_light.png"}></img>
            </RightSliderArrow>
        </Wrapper>);
}

export default home;

I'm getting 'img' from it's parent and that is an array.


import React, { useState } from 'react';
function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);
  const a = () => {
    setCount(count + 1);
  };
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={a}>Click me</button>
    </div>
  );
}
export default Example;