In react project, different front-end developers have different coding habits. After react16.8 hooks fully switch to functional programming, developers have more freedom to write and design patterns. Functions return JSX and functional components are written in different ways:

const App = () = > {
  // A normal function
  const normalFn = () = > {
    return <div>Normal functions return JSX</div>;
  };
  // Functional components
  const FnComp = () = > {
    return <div>Functional component</div>;
  };
  return (
    <div>
      {normalFn()}
      <FnComp />
    </div>
  );
};
export default App;
Copy the code

Both are common in real development, but what are the differences and connections between the two, and what are the pitfalls?

  1. You can receive bothprops, returns a JSX
  2. A normal function returns JSX, which has no state of its own. Cannot use hooks in itnormalFn()
  3. Function components are the standard React components. The first letter must be capitalized<FnComp />The key thing is that you can use hooks, have your own state and life cycle.

If you simply return a JSX reusable component, the effect is the same. However, as the requirements change during development, stateless components may need to be added to the state. In particular, normal functions return components wrapped in other libraries.

// Similar code to add the use of ANTD components
import { useState } from 'react';
import { Select } from 'antd';
const { Option } = Select;
const App = () = > {
  const [state, setstate] = useState(0);
  const normalFn = () = > {
    function handleChange1(value: any) {
      console.log(`selected ${value}`);
    }
    return (
      <div>
        <Select style={{ width: 120 }} onChange={handleChange1}>
          <Option value="Jack111">Jack111</Option>
          <Option value="Lucy111">Lucy111</Option>
        </Select>
      </div>
    );
  };

  const FnComp = () = > {
    function handleChange2(value: any) {
      console.log(`selected ${value}`);
    }
    return (
      <div>
        <Select style={{ width: 120 }} onChange={handleChange2}>
          <Option value="Jack222">Jack222</Option>
          <Option value="Lucy222">Lucy222</Option>
        </Select>
      </div>
    );
  };
  return (
    <div>
      {normalFn()}
      <FnComp />
      <button
        onClick={()= > {
          setstate(state + 1);
        }}
      >
        add
      </button>
      <p>{state}</p>
    </div>
  );
};

export default App;
Copy the code

The code above is very simple. Both normalFn and FnComp return the same Select component, while the App component adds useState logic to trigger state changes by clicking a button. Select is rendered by a normal function to save the previous option, while functional components are rendered to reset to null. Why does this problem exist?

  1. When I click the button, the state changes,AppThe component is re-rendered, so this App function is re-executed
  2. Functional componentFnCompDestroy and rerender, and any states or functions that may exist inside are also destroyed and reset, soSelectThe value of is reset to null
  3. Common functionnormalFnReturns aantdSelectComponent, which is actually used from the sourcereact-component/selectThis component, this component is used in the internal implementationReact.useState Click here to view the source code.This is equivalent to using hooks inside a normal function, which is the root cause of the discrepancy.

So just to conclude

  1. If it is very simple logic or if you are sure that the component you are returning has no internal state, then you can use normal functions to encapsulate the code during development.
  2. When your component has internal state, or needs caching to optimize performance, you can only use functional components.
  3. In order to avoid painful changes to the code, try to functional components.